I am attempting to upload an Excel document created using the NPOI library to a SharePoint Online site using the Microsoft Graph API.
When I write the Excel file to my local machines user directory, I'm able to open the generated TestExcelUpload.xslx
file without issue and see the 'ColOne', 'ColTwo', 'ColThree' entries.
However, when I upload the Excel file to the SharePoint Online site, I can see the file gets created, but when I attempt to open it I get the error message Sorry, we couldn't find 'https://company.sharepoint.com/sites/Technology/Shared Documents/Tool/Data/TestExcelUpload.xlsx'. Is it possible it was moved, renamed or deleted?
. If I download the file, I can see it has a Size of 0 bytes. So I think the issue is to do with how I am doing the upload - I attempted to follow the sample from the Microsoft docs - https://learn.microsoft.com/en-us/graph/api/driveitem-put-content?msclkid=5dab86cad12711ec91c842a089f27412&view=graph-rest-1.0&tabs=csharp.
The code below is where I am with it:
Would anyone be able to tell me where I might be going wrong?
public async Task ExcelUploadToSharePointTest()
{
// 1. Create basic excel .xlsx workbook using NPOI v2.5.6
var testColumnData = new List<string> { "ColOne", "ColTwo", "ColThree" };
var workbook = new XSSFWorkbook();
var sheet1 = workbook.CreateSheet();
var row1 = sheet1.CreateRow(0);
for (var i = 0; testColumnData.Count > i; i++)
{
row1.CreateCell(i).SetCellValue(testColumnData[i]);
}
// 2. Write workbook to local user directory - works
await using (var fileSteam = new FileStream($"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/TestExcelUpload.xlsx", FileMode.Create))
{
workbook.Write(fileSteam, true);
}
// 3. Write workbook to SharePoint online, by saving to memory stream and uploading using Graph API - not working
var siteBase = await _graphServiceClient.Sites
.GetByPath("/sites/Technology", "company.sharepoint.com")
.Request()
.GetAsync();
var rootFolder = _graphServiceClient.Sites[siteBase.Id].Drive.Root;
await using (var memoryStream = new MemoryStream())
{
workbook.Write(memoryStream, true);
await rootFolder.ItemWithPath("Tool/Data/TestExcelUpload.xlsx").Content.Request().PutAsync<DriveItem>(memoryStream);
}
}
It looks like that you need to set memoryStream.Position
to 0.
When you call workbook.Write(memoryStream, true)
then the current position within the stream is same as the length of the stream and therefore zero bytes are uploaded.
await using (var memoryStream = new MemoryStream())
{
workbook.Write(memoryStream, true);
memoryStream.Position = 0;
await rootFolder.ItemWithPath("Tool/Data/TestExcelUpload.xlsx").Content.Request().PutAsync<DriveItem>(memoryStream);
}