Create excel file through Microsoft Graph API - excel

Does anyone know how to create excel and ppt files through the MS Graph API? We're trying to leverage the MS Graph API to create word/excel/ppt files on a button click and while we found how to create word files, the excel and powerpoint files created are corrupted even with a success response from the api. The end point below works for the word files. We've been just working with the graph api explorer (https://developer.microsoft.com/en-us/graph/graph-explorer#) for now. Any help would be appreciated!
POST https://graph.microsoft.com/v1.0/drives/{Drive ID}/root/children/
Request Body:
{
"name": "FileTest6.docx",
"file":{
}
}

PowerPoint files
PowerPoint files could be created via DriveItem upload endpoint, for example:
PUT https://graph.microsoft.com/v1.0/me/drive/root:/sample.pptx:/content
or
POST https://graph.microsoft.com/v1.0/me/drive/root/children
{
"name": "Sample.pptx",
"file":{ }
}
Excel files
With excel files the situation is a bit different since the content of the excel file to be uploaded needs to be provided explicitly.
For ASP.NET Core application the following solution could be considered:
create empty Excel document via Open XML SDK (see CreateWorkbook example below)
upload it via DriveItem upload endpoint
C# example
using (var stream = new MemoryStream())
{
CreateWorkbook(stream);
stream.Seek(0, SeekOrigin.Begin);
var driveItem = await graphClient.Me
.Drive
.Root
.ItemWithPath("SampleWorkbook1.xlsx")
.Content
.Request()
.PutAsync<DriveItem>(stream);
}
where
public static void CreateWorkbook(Stream stream)
{
// By default, AutoSave = true, Editable = true, and Type = xlsx.
var spreadsheetDocument =
SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
// Add a WorkbookPart to the document.
var workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
// Add a WorksheetPart to the WorkbookPart.
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
var sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
var sheet = new Sheet()
{Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "mySheet"};
sheets.Append(sheet);
workbookpart.Workbook.Save();
// Close the document.
spreadsheetDocument.Close();
}

Related

Embedding Excel Add-Ins with OpenXml

My team is working on an Office 365 add-in for Excel, and as part of the project, we’re creating Excel documents through the GraphAPI with the end goal of having the add-in already setup for the document. We’re using the .NET OpenXml library to create the document before copying it through the GraphAPI.
We haven’t been able to find many resources for how to setup an add-in through OpenXml and have not been able to get anything working. The last thing we tried was copying the example we found here, but we couldn’t get it working. Does anyone know how to setup add-ins using the OpenXml library?
Note: the add-in is already in the Office Add-Ins store, and we have information like the AppSource ID.
Thank you!
We're actually about to publish a new sample around this scenario. The sample shows how to create an Excel document using OOXML, embed your add-in, and then upload the file to OneDrive. It also creates a Team chat that links to the file.
You can try out the sample here: Open data from your web site in a spreadsheet in Microsoft Teams
Or give us feedback on the PR: https://github.com/OfficeDev/PnP-OfficeAddins/pull/197
To answer your question about how to embed the add-in, you need to create a web extension section. I've copied the relevant code here. Note this is the same code from the Office-OOXML-EmbedAddin sample you already looked at. We reused it for the new sample. You can change the CUSTOM MODIFICATION section to provide any custom properties you want to your add-in when it opens.
// Embeds the add-in into a file of the specified type.
private void EmbedAddin(SpreadsheetDocument spreadsheet)
{
spreadsheet.DeletePart(spreadsheet.WebExTaskpanesPart);
var webExTaskpanesPart = spreadsheet.AddWebExTaskpanesPart();
CreateWebExTaskpanesPart(webExTaskpanesPart);
}
// Adds child parts and generates content of the specified part.
private void CreateWebExTaskpanesPart(WebExTaskpanesPart part)
{
WebExtensionPart webExtensionPart1 = part.AddNewPart<WebExtensionPart>("rId1");
GenerateWebExtensionPart1Content(webExtensionPart1);
GeneratePartContent(part);
}
// Generates content of webExtensionPart1.
private void GenerateWebExtensionPart1Content(WebExtensionPart webExtensionPart1)
{
// Add web extension containg Id for Script Lab add-in
We.WebExtension webExtension1 = new We.WebExtension() { Id = "{635BF0CD-42CC-4174-B8D2-6D375C9A759E}" };
webExtension1.AddNamespaceDeclaration("we", "http://schemas.microsoft.com/office/webextensions/webextension/2010/11");
// Add store information for Script Lab add-in
We.WebExtensionStoreReference webExtensionStoreReference1 = new We.WebExtensionStoreReference() { Id = "wa104380862", Version = "1.1.0.0", Store = "en-US", StoreType = "OMEX" };
We.WebExtensionReferenceList webExtensionReferenceList1 = new We.WebExtensionReferenceList();
We.WebExtensionPropertyBag webExtensionPropertyBag1 = new We.WebExtensionPropertyBag();
// Add the property that makes the taskpane visible.
We.WebExtensionProperty webExtensionProperty1 = new We.WebExtensionProperty() { Name = "Office.AutoShowTaskpaneWithDocument", Value = "true" };
webExtensionPropertyBag1.Append(webExtensionProperty1);
// CUSTOM MODIFICATION BEGIN
// Add the property that specifies the snippet to import.
string snippetToImportValue = string.Format("{{\"type\":\"gist\",\"id\":\"{0}\"}}", "{72189570-AE11-4207-9DEE-C8BDE4B83188}");
We.WebExtensionProperty webExtensionProperty2 = new We.WebExtensionProperty() { Name = "SnippetToImport", Value = snippetToImportValue };
webExtensionPropertyBag1.Append(webExtensionProperty2);
// CUSTOM MODIFICATION END
We.WebExtensionBindingList webExtensionBindingList1 = new We.WebExtensionBindingList();
We.Snapshot snapshot1 = new We.Snapshot();
snapshot1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
webExtension1.Append(webExtensionStoreReference1);
webExtension1.Append(webExtensionReferenceList1);
webExtension1.Append(webExtensionPropertyBag1);
webExtension1.Append(webExtensionBindingList1);
webExtension1.Append(snapshot1);
webExtensionPart1.WebExtension = webExtension1;
}
// Generates content of part.
private void GeneratePartContent(WebExTaskpanesPart part)
{
Wetp.Taskpanes taskpanes1 = new Wetp.Taskpanes();
taskpanes1.AddNamespaceDeclaration("wetp", "http://schemas.microsoft.com/office/webextensions/taskpanes/2010/11");
Wetp.WebExtensionTaskpane webExtensionTaskpane1 = new Wetp.WebExtensionTaskpane() { DockState = "right", Visibility = true, Width = 350D, Row = (UInt32Value)4U };
Wetp.WebExtensionPartReference webExtensionPartReference1 = new Wetp.WebExtensionPartReference() { Id = "rId1" };
webExtensionPartReference1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
webExtensionTaskpane1.Append(webExtensionPartReference1);
taskpanes1.Append(webExtensionTaskpane1);
part.Taskpanes = taskpanes1;
}

Export WebGrid data to Excel in MVC4

I want to export WebGrid data to excel with formatting.
I have written below code which export WebGrid data to Excel.
WebGrid grid = new WebGrid(source: listReport, canPage: false, canSort: false);
string gridData = grid.GetHtml(
columns: grid.Columns(
grid.Column("ID", "ID"),
grid.Column("Name", "Name"),
grid.Column("Summary", "Summary"),
grid.Column("Detail", "Detail"),
grid.Column("ProjectName", "Project Name")
)
).ToString();
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=CustomerInfo.xls");
Response.ContentType = "application/excel";
Response.Write(gridData);
Response.End();
I want to do formatting in excel.
Is it possible to export data with formatting?
Also it gives me below error when i open the generated excel
You haven't actually created an Excel file. You've created an HTML file masquerading as an Excel 2003 file, which is a bad idea. I explain why and cover some alternatives on my blog.
Styling will be difficult, because of the way you're creating the source HTML. You could parse it with a library, then add basic styling via each elements style attribute. Or instead of using WebGrid you can manually build your HTML.
string html = "<table style='color:red'><tr><td>Hello, world!</td></tr></table>";
But really, the best thing to do is generate real Excel files. Here's a quick excerpt from my blog using EPPlus. It's shown in Web Forms. In MVC you'd actually want to return a FileResult rather than writing directly to the response.
protected void ExportBtn_Click(object sender, EventArgs e)
{
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=myexcelfile.xlsx");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var package = new ExcelPackage(); //create a new package, this is the equivalent of an XLSX file.
var sheet = package.Workbook.Worksheets.Add("My Data"); //Add a new sheet to the workbook
var dt = GetDataTable(); //This retrieves a System.Data.DataTable, you'd likely get it from your database.
sheet.Cells["A1"].LoadFromDataTable(dt, true); //EPPlus contains helper function to load data from a DataTable, though you could manually fill in rows/column values yourself if you want
var range = sheet.Cells[1, 1, dt.Rows.Count + 1, 2]; //We're getting a reference to all the cells that contain data
var table = sheet.Tables.Add(range, "My Data Table"); //Creating an Excel table
table.TableStyle = TableStyles.Medium8; //Setting the table style to something that looks nice
range.AutoFitColumns(); //Auto fitting the column widths.
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
}

Exception when open excel: File contains corrupted data

I am trying to read an excel with OpenXML.
What I did is simply as following:
private WorkbookPart wbPart = null;
private SpreadsheetDocument document = null;
public byte[] GetExcelReport()
{
byte[] original = File.ReadAllBytes(this.originalFilename);
using (MemoryStream stream = new MemoryStream())
{
stream.Write(original, 0, original.Length);
using (SpreadsheetDocument excel = SpreadsheetDocument.Open(stream, true))
{
this.document = excel;
this.wbPart = document.WorkbookPart;
UpdateValue();
}
stream.Seek(0, SeekOrigin.Begin);
byte[] data = stream.ToArray();
return data;
}
}
I initialized this.originalFilename in the constructor. It is the filename ended with '.xlsx' which i created with excel 2010.
But this line of code
using (SpreadsheetDocument excel = SpreadsheetDocument.Open(stream, true))
gives the exception: Message: System.IO.FileFormatException: File contains corrupted data.
The StackTrace:
Does anyone know how to solve this problem? At the beginning, I didn't use the Stream, I just use SpreadsheetDocument.Open(filename, true). However, it turns out to be exactly the same exception.
I've tried to create a new .xlsx file, but it's still the same.
There is a MSDN page which describes the process of reading and writing Excel file using stream and open xml SDK.
http://msdn.microsoft.com/en-us/library/office/ff478410.aspx
Try extracting the document contents through zip application and check whether you are getting the standard folders inside like xl,docProps and _rels etc.,
This is a method to find whether the package is properly packaged as archive or not.
Hope this helps.

Upload document from Local Machine to SharePoint 2013 Library using WebService

I have following code from http://ktskumar.wordpress.com/2009/03/03/upload-document-from-local-machine-to-sharepoint-library/ to upload a document to a sharepoint library using web services. I have added https://mysite.sharepoint.com/_vti_bin/Copy.asmx (this site is on sharepoint Online) as my service reference.
//Copy WebService Settings
string webUrl = "https://mySite.sharepoint.com";
WSCopy.Copy copyService = new WSCopy.Copy();
copyService.Url = webUrl + "/_vti_bin/copy.asmx";
copyService.Credentials = System.Net.CredentialCache.DefaultCredentials;
//Source and Destination Document URLs
string sourceUrl = "http://localhost/Shared Documents/Sample.doc";
string destinationUrl = "E:\\DocumentsSample.doc";
//Variables for Reading metadata’s of a document
WSCopy.FieldInformation fieldInfo = new WSCopy.FieldInformation();
WSCopy.FieldInformation[] fieldInfoArray = { fieldInfo };
WSCopy.CopyResult cResult1 = new WSCopy.CopyResult();
WSCopy.CopyResult cResult2 = new WSCopy.CopyResult();
WSCopy.CopyResult[] cResultArray = { cResult1, cResult2 };
//Receive a Document Contents into Byte array (filecontents)
byte[] fileContents = new Byte[4096];
uint copyresult = copyService.GetItem(sourceUrl, out fieldInfoArray, out fileContents);
if (copyresult == 0)
{
Console.WriteLine("Document downloaded Successfully, and now it's getting saved in location " + destinationUrl);
//Create a new file and write contents to that document
FileStream fStream = new FileStream(destinationUrl, FileMode.Create, FileAccess.ReadWrite);
fStream.Write(fileContents, 0, fileContents.Length);
fStream.Close();
}
else
{
Console.WriteLine("Document Downloading gets failed...");
}
Console.Write("Press any key to exit...");
Console.Read();
here WSCopy is the service reference and 'WSCopy.Copy' copy class is not found on my project. How can i resolve this or is there another way to achive my goal.
Refer to this post
http://www.ktskumar.com/blog/2009/03/upload-document-from-local-machine-to-sharepoint-library/
You have to add the web service url in Web Reference, instead of Service Reference.
On Visual Studio Project, Right click the References, and select the Add Service Reference.
On Add Service Reference popup, click the Advanced button on bottom of the box,
Now the Service Reference Settings popup will open, there we have to click the “Add Web Reference” botton. Then give the Web Service url and click the “Add Reference” button to include webservice url to the project.

How do I save an Excel workbook to disk?

I am dynamically creating a Excel File that is displayed to the users upon creation, however I now need to also save the file onto the server.
How would I save it to a specific folder?
I have the following code
public void ExportMembers()
{
Microsoft.Office.Interop.Excel.Application xla = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = xla.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet ws = (Worksheet)xla.ActiveSheet;
ws.Cells[1, 1] = "Site Id";
//I create the rest of the cells here
xla.Visible = true; //this displays the excel spreadsheet to the user
//client id code is here
if (!System.IO.Directory.Exists("/Files/" + clientId + "/Excel"))
{ //if doesn't exist make folder
System.IO.Directory.CreateDirectory("/Files/" + clientId);
System.IO.Directory.CreateDirectory("/Files/" + clientId + "/Excel");
}
//save the xla as a file Here
}
How do I save the spreadsheet on the server?
Any help is appreciated.
Thanks
see the Save method for Microsoft.Office.Interop.Excel.Application
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._application.save

Resources