2
votes

I am currently forced to use Office Live / Skydrive (whatever the proper name is) to edit Excel workbooks. Skydrive won't let me upload a workbook that contains macros, and I don't need the macros, so I would like to write a little cleansing app in C# that simply removes all macros. How can I go about this using Excel 2007 and above (.xlsm) documents?

EDIT: Basically, I would like to open an xlsm document and save it as an xlsx document, without required Excel to be installed, i.e. via the OpenXML SDK or something.

3
.xlsx documents don't have macrosDavid Heffernan
@David, yeah, thanks. I haven't had much xlsx/m exposure lately, not having office. Maybe it will just be easier for the user to send me an xlsx doc, then it will already have no macros.ProfK

3 Answers

1
votes

I didn't have time to check the thousands of pages in the OpenXML SDK documentation but you could try something like this:

The .xlsm file is a ZIP archive containing mostly XML files. You need to remove the references to macros from the workbook.xml.rels file in the xl\_rels folder. Here is a sample:

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  <Relationship Target="worksheets/sheet3.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Id="rId3"/>
  <Relationship Target="worksheets/sheet2.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Id="rId2"/>
  <Relationship Target="worksheets/sheet1.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Id="rId1"/>
  <Relationship Target="vbaProject.bin" Type="http://schemas.microsoft.com/office/2006/relationships/vbaProject" Id="rId6"/>
  <Relationship Target="styles.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Id="rId5"/>
  <Relationship Target="theme/theme1.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Id="rId4"/>
</Relationships>

It is the relationship of type http://schemas.microsoft.com/office/2006/relationships/vbaProject you need to remove. The file referenced in the relationship should also be removed from the ZIP archive. In this case the file is named vbaProject.bin and is placed in the xl folder.

Using the OpenXML SDK you should be able to navigate the logical structure of the Excel file and perform this kind of cleanup without understanding the exact structure of the ZIP archive. However, inspecting the Excel file as if it was a ZIP archive can still be helpful to understand the structure of the file.

2
votes

With openXML SDK 2.0, this worked for me:

SpreadsheetDocument document = SpreadsheetDocument.Open("excelFile.xlsm", true);
document.WorkbookPart.DeletePart(document.WorkbookPart.VbaProjectPart);
document.Dispose();
1
votes

One thing you could try is to change the document type of the file you are receiving as explained in a previous answer. The available options to pass into the ChangeDocumentType method are found here.

I am not totally sure this will strip all the macro content, but its worth a shot if you aren't able to get a .xlsx file from your user.