如何修改C#OpenXML生成的Excel[Content_Types].xml文件
How to modify Excel [Content_Types].xml file generated by C# OpenXML
我正在使用 OpenXML SDK 库在 C# 中生成 Excel 文件。
我注意到生成的内容文件 ([Content_Types].xml) 不同于 Excel 在保存文件时生成的内容。
由于某些原因,我的 OpenXML 生成的文件缺少
<Default ContentType="application/xml" Extension="xml"/>
元素并放置
<Default Extension="xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />
元素代替。
OpenXML 生成的文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
<Default Extension="xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" />
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" />
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" />
<Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml" />
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" />
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
</Types>
我想实现以下目标:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"/>
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="xml" ContentType="application/xml"/>
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
<Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
</Types>
这也是一个缺失的元素,我想补充一下
<Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"/>
有没有办法使用 OpenXML 库访问内容类型?
我想避免手动解压 xlsx 文件并修改 [Content_Types].xml
的源代码的方法
using (var archive = ZipFile.Open(filePath, ZipArchiveMode.Update))
{
var entry = archive.GetEntry("[Content_Types].xml");
//Replace the content
StringBuilder sb = new StringBuilder();
sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>");
sb.Append("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">");
//sb.Append("<Default Extension=\"bin\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings\"/>");
sb.Append("<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>");
sb.Append("<Default Extension=\"xml\" ContentType=\"application/xml\"/>");
sb.Append("<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\" />");
sb.Append("<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\" />");
sb.Append("<Override PartName=\"/xl/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\" />");
sb.Append("<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\" />");
sb.Append("<Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\" />");
sb.Append("<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\" />");
sb.Append("<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\" />");
sb.Append("</Types>");
entry.Delete();
entry = archive.CreateEntry([Content_Types].xml);
using (StreamWriter writer = new StreamWriter(entry.Open()))
{
writer.Write(sb);
}
}
最简单的解决方案是使用具有所需内容类型的适当 Excel 工作簿作为起点。
使用 Open XML SDK,您可以从 Excel 模板 (.xslt) 创建工作簿或克隆现有 Excel 工作簿(.xlsx、.xlsm)。您可以通过在现有 SpreadsheetDocument
对象上调用 Clone()
方法或通过将数据读入 MemoryStream
,打开 MemoryStream
上的 SpreadsheetDocument
来克隆工作簿],然后在最后将其保存到不同的文件(或数据库或其他文件)。
以下示例从模板(或工作簿)创建 Excel 工作簿:
SpreadsheetDocument doc = SpreadsheetDocument.CreateFromTemplate("Template.xlst");
如果您查看 CreateFromTemplate()
方法的实现方式,您会发现它总是克隆工作簿或模板。对于模板,它会更改文档类型(使用 ChangeDocumentType()
方法),这样您将始终获得工作簿而不是模板。因此,如果您的入门模板或工作簿存储在文件系统中,这将是最直接的方法。
根据您的 "template" 的存储方式和存储位置,还有其他方法可以达到相同的效果。但是,您通常会使用模板或工作簿数据生成 Stream
(例如,MemoryStream
),然后在 Stream
.
上打开 SpreadsheetDocument
我正在使用 OpenXML SDK 库在 C# 中生成 Excel 文件。 我注意到生成的内容文件 ([Content_Types].xml) 不同于 Excel 在保存文件时生成的内容。
由于某些原因,我的 OpenXML 生成的文件缺少
<Default ContentType="application/xml" Extension="xml"/>
元素并放置
<Default Extension="xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />
元素代替。
OpenXML 生成的文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
<Default Extension="xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" />
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" />
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" />
<Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml" />
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" />
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
</Types>
我想实现以下目标:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"/>
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="xml" ContentType="application/xml"/>
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
<Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
</Types>
这也是一个缺失的元素,我想补充一下
<Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"/>
有没有办法使用 OpenXML 库访问内容类型? 我想避免手动解压 xlsx 文件并修改 [Content_Types].xml
的源代码的方法 using (var archive = ZipFile.Open(filePath, ZipArchiveMode.Update))
{
var entry = archive.GetEntry("[Content_Types].xml");
//Replace the content
StringBuilder sb = new StringBuilder();
sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>");
sb.Append("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">");
//sb.Append("<Default Extension=\"bin\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings\"/>");
sb.Append("<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>");
sb.Append("<Default Extension=\"xml\" ContentType=\"application/xml\"/>");
sb.Append("<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\" />");
sb.Append("<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\" />");
sb.Append("<Override PartName=\"/xl/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\" />");
sb.Append("<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\" />");
sb.Append("<Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\" />");
sb.Append("<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\" />");
sb.Append("<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\" />");
sb.Append("</Types>");
entry.Delete();
entry = archive.CreateEntry([Content_Types].xml);
using (StreamWriter writer = new StreamWriter(entry.Open()))
{
writer.Write(sb);
}
}
最简单的解决方案是使用具有所需内容类型的适当 Excel 工作簿作为起点。
使用 Open XML SDK,您可以从 Excel 模板 (.xslt) 创建工作簿或克隆现有 Excel 工作簿(.xlsx、.xlsm)。您可以通过在现有 SpreadsheetDocument
对象上调用 Clone()
方法或通过将数据读入 MemoryStream
,打开 MemoryStream
上的 SpreadsheetDocument
来克隆工作簿],然后在最后将其保存到不同的文件(或数据库或其他文件)。
以下示例从模板(或工作簿)创建 Excel 工作簿:
SpreadsheetDocument doc = SpreadsheetDocument.CreateFromTemplate("Template.xlst");
如果您查看 CreateFromTemplate()
方法的实现方式,您会发现它总是克隆工作簿或模板。对于模板,它会更改文档类型(使用 ChangeDocumentType()
方法),这样您将始终获得工作簿而不是模板。因此,如果您的入门模板或工作簿存储在文件系统中,这将是最直接的方法。
根据您的 "template" 的存储方式和存储位置,还有其他方法可以达到相同的效果。但是,您通常会使用模板或工作簿数据生成 Stream
(例如,MemoryStream
),然后在 Stream
.
SpreadsheetDocument