Search code examples
google-sheetsopenxml-sdk

Avoid Google Spreadsheet to convert an XLSX file created by Open XML SDK to XLSM


I am using the Open XML SDK 2.14.0 to create Excel files. If I upload the XLSX file produced by Open XML SDK to Google Spreadsheet, it opens the file as an XLSX file but if I make any change in the spreadsheet then Google Spreadsheet changes the file type to XLSM.

The minimalistic code bellow (found in the official documentation) reproduces the issue I am having. It generate a foo.xlsx file in C:\Temp.

var filepath = @"C:\temp\foo.xlsx";

// Create a spreadsheet document by supplying the filepath.
// By default, AutoSave = true, Editable = true, and Type = xlsx.
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);

// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();

// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());

// Add Sheets to the Workbook.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());

// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "mySheet" };
sheets.Append(sheet);

workbookpart.Workbook.Save();

// Close the document.
spreadsheetDocument.Close();

If I upload the generated file to Google Spreadsheet, it shows this is an XLSX file.

enter image description here

But if I change anything in the workbook then Google Spreadsheet changes the file type to XLSM.

enter image description here

If I generate an empty workbook from MS Excel (Office 360) I don't have this issue : Google Spreadsheet will not change the file type if I change the data.

Why does Google Spreadsheet behave like this with XLSX file generated by Open XML SDK ? What should I do to produce an XLSX file with the Open XML SDK that is not converted to XLSM by Google Spreadsheet ?


Solution

  • A nice person from the OfficeDev team found the solution : https://github.com/OfficeDev/Open-XML-SDK/issues/1093

    I am posting here the solution. It seems we need to call spreadsheetDocument.AddCoreFilePropertiesPart();

    Thus my code looks like :

    var filepath = @"C:\temp\foo.xlsx";
    
    // Create a spreadsheet document by supplying the filepath.
    // By default, AutoSave = true, Editable = true, and Type = xlsx.
    SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);
    var coreFilePropPart = spreadsheetDocument.AddCoreFilePropertiesPart();
    
    // With DocumentFormat.OpenXml 2.14.0, AddCoreFilePropertiesPart includes an empty core.xml without a root which leads to an error when the generated file is opened in Excel
    using (XmlTextWriter writer = new XmlTextWriter(coreFilePropPart.GetStream(FileMode.Create), System.Text.Encoding.UTF8))
    {
      writer.WriteRaw("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<cp:coreProperties xmlns:cp=\"https://schemas.openxmlformats.org/package/2006/metadata/core-properties\"></cp:coreProperties>");
      writer.Flush();
    }
    
    // Add a WorkbookPart to the document.
    WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
    workbookpart.Workbook = new Workbook();
    
    // Add a WorksheetPart to the WorkbookPart.
    WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
    worksheetPart.Worksheet = new Worksheet(new SheetData());
    
    // Add Sheets to the Workbook.
    Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
    
    // Append a new worksheet and associate it with the workbook.
    Sheet sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "mySheet" };
    sheets.Append(sheet);
    
    workbookpart.Workbook.Save();
    
    // Close the document.
    spreadsheetDocument.Close();
    

    And thus Google sheets stop changing from XLSX to XLSM !