如何修改由C#OpenXML生成的Excel[Content_Types].xml文件

如何修改由C#OpenXML生成的Excel[Content_Types].xml文件,c#,excel,openxml,content-type,openxml-sdk,C#,Excel,Openxml,Content Type,Openxml Sdk,我正在使用库在C#中生成Excel文件。 我注意到生成的内容文件([content\u Types].xml)与保存文件时Excel生成的不同 出于某种原因,我的OpenXML生成的文件缺少 <Default ContentType="application/xml" Extension="xml"/> 元素并放置 元素 OpenXML生成的文件如下所示: <?xml version="1.0" encoding="utf-8"?> <Types xmlns

我正在使用库在C#中生成Excel文件。 我注意到生成的内容文件([content\u Types].xml)与保存文件时Excel生成的不同

出于某种原因,我的OpenXML生成的文件缺少

<Default ContentType="application/xml" Extension="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库访问内容类型的方法? 我希望避免使用(var archive=ZipFile.Open(filePath,ZipArchiveMode.Update))手动解包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);
        }
    }
{ var entry=archive.GetEntry(“[Content\u Types].xml”); //替换内容 StringBuilder sb=新的StringBuilder(); 某人加上(“”); 某人加上(“”); //某人加上(“”); 某人加上(“”); 某人加上(“”); 某人加上(“”); 某人加上(“”); 某人加上(“”); 某人加上(“”); 某人加上(“”); 某人加上(“”); 某人加上(“”); 某人加上(“”); entry.Delete(); entry=archive.CreateEntry([Content\u Types].xml); 使用(StreamWriter=newstreamwriter(entry.Open())) { 写(某人); } }
最简单的解决方案是使用适当的Excel工作簿,以所需的内容类型作为起点

使用OpenXMLSDK,您可以从Excel模板(.xslt)创建工作簿或克隆现有Excel工作簿(.xlsx、.xlsm)。您可以通过对现有的
电子表格文档
对象调用
clone()
方法,或者通过将数据读入
内存流
,打开该
内存流
上的
电子表格文档
,然后在最后将其保存到其他文件(或数据库或其他任何文件)来克隆工作簿

以下示例使用模板(或工作簿)创建Excel工作簿:

SpreadsheetDocument doc=SpreadsheetDocument.CreateFromTemplate(“Template.xlst”);
如果查看
CreateFromTemplate()
方法是如何实现的,您会发现它总是克隆工作簿或模板。对于模板,它随后会更改文档类型(使用
ChangeDocumentType()
方法),以便您始终获得工作簿而不是模板。因此,如果初学者模板或工作簿存储在文件系统中,这将是最简单的方法


根据“模板”的存储方式和位置,还有其他方法可以实现相同的结果。但是,您通常会使用模板或工作簿数据生成一个
(例如
内存流
),然后打开该
流上的
电子表格文档

为什么更改这些文件很重要?涉及哪个版本的Excel?openxmlsdk默认为与office2007兼容。因此,较新版本的Excel可能会生成不同的内容。OpenXMLSDK不支持直接访问这些内容。您可以尝试在Excel中打开这样一个文件,做一个小的更改使其变为“脏”,然后保存到一个新的文件名。在OpenXMLSDK生产力工具中打开原始版本,然后使用比较功能打开更改后的版本。这将向您显示将第一个文件“转换”为第二个文件的代码。由于某些原因,此操作失败,出现“外部表未采用预期格式”错误。我知道使用EPPlus Lib,OLE可以解析文件。可能是出于好奇,也可能是因为我太固执,我想使用OpenXML执行此操作。其目的是生成与EPPlus或Excel完全相同的文件。