c# - 我想根据从 ASP.NET Core 6 的 API 收到的 XML 字符串创建 docx 文件

标签 c# xml webapi openxml-sdk asp.net-core-6.0

这是我从压缩的 docx 文件中获取的 xml 文件。

这是 document.xml:

<w:document 
xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" 
xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" 
xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" 
xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" 
xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" 
xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" 
xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" 
xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" 
xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" 
xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" 
xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" 
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" 
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" 
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" 
xmlns:v="urn:schemas-microsoft-com:vml" 
xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" 
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" 
xmlns:w10="urn:schemas-microsoft-com:office:word" 
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" 
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" 
xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" 
xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" 
xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" 
xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" 
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" 
xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" 
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" 
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" 
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" 
mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14">
<w:body>
<w:p w14:paraId="59E8928B" w14:textId="4F989F00" w:rsidR="00E57A39" w:rsidRPr="008F41DD" w:rsidRDefault="008F41DD" w:rsidP="008F41DD">
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
</w:pPr>
<w:r w:rsidRPr="008F41DD">
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
<w:t xml:space="preserve">One </w:t>
</w:r>
</w:p>
<w:p w14:paraId="2D18B139" w14:textId="40831F20" w:rsidR="008F41DD" w:rsidRPr="008F41DD" w:rsidRDefault="008F41DD" w:rsidP="008F41DD">
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
</w:pPr>
<w:r w:rsidRPr="008F41DD">
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
<w:t>Two</w:t>
</w:r>
</w:p>
<w:p w14:paraId="4E1C2299" w14:textId="45351C9E" w:rsidR="008F41DD" w:rsidRPr="008F41DD" w:rsidRDefault="008F41DD" w:rsidP="008F41DD">
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
</w:pPr>
<w:r w:rsidRPr="008F41DD">
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
<w:t>Three</w:t>
</w:r>
</w:p>
<w:p w14:paraId="07C809C6" w14:textId="10C92B2E" w:rsidR="008F41DD" w:rsidRPr="008F41DD" w:rsidRDefault="008F41DD" w:rsidP="008F41DD">
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
</w:pPr>
<w:r w:rsidRPr="008F41DD">
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
<w:t>Four</w:t>
</w:r>
</w:p>
<w:p w14:paraId="2DB3ADA1" w14:textId="2F165FEA" w:rsidR="008F41DD" w:rsidRPr="008F41DD" w:rsidRDefault="008F41DD" w:rsidP="008F41DD">
<w:pPr>
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
</w:pPr>
</w:p>
<w:p w14:paraId="086A6010" w14:textId="77777777" w:rsidR="008F41DD" w:rsidRPr="008F41DD" w:rsidRDefault="008F41DD" w:rsidP="008F41DD">
<w:pPr>
<w:rPr>
<w:rFonts w:cs="B Nazanin"/>
</w:rPr>
</w:pPr>
</w:p>
<w:sectPr w:rsidR="008F41DD" w:rsidRPr="008F41DD">
<w:pgSz w:w="12240" w:h="15840"/>
<w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/>
<w:cols w:space="720"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
</w:body>
</w:document>

我的项目端点 API 和代码:

[HttpPost("[action]")]
[Consumes("application/xml")]
public IActionResult UploadXml([FromBody] XElement xml)
{
    MemoryStream generatedDocument = new MemoryStream();

    using (WordprocessingDocument package = WordprocessingDocument.Create(generatedDocument, WordprocessingDocumentType.Document))
    {
        var mainPart = package.AddMainDocumentPart();

        var doc = new XmlDocument();
        doc.LoadXml(xml.ToString());

        new Document(doc.OuterXml);
        package.Save();
    }

    var result = generatedDocument.ToArray();

    return File(result, "application/octet-stream", "document.docx");
}

现在我想将所有这些 XML 作为字符串传递到 OpenXML SDK 包,但我不知道如何操作。

我搜索了很多,但无法解决这个问题,我需要一个示例代码来向我展示如何做到这一点。

如果有人以前这样做过,请与我分享您的代码。

我想说,我知道有很多文档,但我应该快速完成此操作,而且我无法阅读 Microsoft 的不良文档。

谢谢

最佳答案

首先,您创建的Document实例在您显示的代码中没有出现。如果您不将其添加到包中,您的文档中将没有任何内容。

这是进行了所需更改的工作代码,基本上消除了不必要的 XmlDocument 摆弄以及不必要的字节数组创建,因为 File 确实接受流。

[HttpPost()]
[Consumes("application/xml")]
public IActionResult UploadXml([FromBody] XElement xml)
{
    MemoryStream generatedDocument = new MemoryStream();

    using (WordprocessingDocument package = WordprocessingDocument.Create(generatedDocument, WordprocessingDocumentType.Document))
    {
        var mainPart = package.AddMainDocumentPart();

        mainPart.Document = new Document(xml.ToString(SaveOptions.DisableFormatting));
        package.Save();
    }

    generatedDocument.Position = 0; // to start of stream!

    return File(generatedDocument, "application/octet-stream", "document.docx");
}

我假设您知道,如果您希望 Action 接受 .Net Core 中的 XElement,则必须启用 Xml 序列化程序,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services
       .AddControllersWithViews( opt => { opt.MaxValidationDepth = 64; })
       .AddXmlSerializerFormatters();
}

我还必须将 MaxValidationDepth 设置为高于默认值 32 的值。对于示例数据,加倍有效。

为了完整起见,这是我的curl测试命令

curl --trace con -H"Content-Type: application/xml" <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5a773e1a2d35283e3e353974223736" rel="noreferrer noopener nofollow">[email protected]</a>  --output doctest.docx  http://localhost:5000/Home/UploadXml

这就是我最终得到的结果:

enter image description here

关于c# - 我想根据从 ASP.NET Core 6 的 API 收到的 XML 字符串创建 docx 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73258129/

相关文章:

java - 服务内的((按钮) View )不起作用

c# - 如何使用 XDocument 打印 <?xml version ="1.0"?>

c# - 客户端从 cosmos db 中存储的延续 token 在哪里以及如何维护

azure - logger.Log 语句在 Azure 门户中的什么位置?

c# - Entity Framework Core OnModelCreating 与 Migration,正确的开发工作流程

c# - 使用 C# 阻止访问目录

php - 无法在 ubuntu 16.04 上安装 simplexml 扩展

c# - 尽管有有效的 Token,为什么我仍会收到未授权的信息?

c# - 为什么 'await'会改变WinForms program.cs中的线程上下文

c# - 如何在MVVM中更改SelectedIndex