当前位置:  开发笔记 > 编程语言 > 正文

将多个DOCX文件附加在一起

如何解决《将多个DOCX文件附加在一起》经验,为你挑选了3个好方法。

我需要以编程方式使用C#将几个预先存在的docx文件附加到一个长docx文件中 - 包括子弹和图像等特殊标记.页眉和页脚信息将被删除,因此这些信息不会导致任何问题.

我可以找到有关docx使用.NET Framework 3 操作单个文件的大量信息,但对于如何合并文件没有任何简单或明显的信息.还有一个第三方程序(Acronis.Words)可以做到这一点,但它非常昂贵.

更新:

已经建议通过Word进行自动化,但是我的代码将在IIS Web服务器上的ASP.NET上运行,因此对我而言,不能选择使用Word.很抱歉没有提到这一点.



1> GRGodoi..:

尽管提交了所有好的建议和解决方案,我还是开发了另一种选择.在我看来,你应该完全避免在服务器应用程序中使用Word.所以我使用OpenXML,但它不适用于AltChunk.我将文本添加到原始主体,我收到了一个byte []列表而不是文件名列表,但您可以轻松地根据需要更改代码.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

namespace OfficeMergeControl
{
    public class CombineDocs
    {
        public byte[] OpenAndCombine( IList documents )
        {
            MemoryStream mainStream = new MemoryStream();

            mainStream.Write(documents[0], 0, documents[0].Length);
            mainStream.Position = 0;

            int pointer = 1;
            byte[] ret;
            try
            {
                using (WordprocessingDocument mainDocument = WordprocessingDocument.Open(mainStream, true))
                {

                    XElement newBody = XElement.Parse(mainDocument.MainDocumentPart.Document.Body.OuterXml);

                    for (pointer = 1; pointer < documents.Count; pointer++)
                    {
                        WordprocessingDocument tempDocument = WordprocessingDocument.Open(new MemoryStream(documents[pointer]), true);
                        XElement tempBody = XElement.Parse(tempDocument.MainDocumentPart.Document.Body.OuterXml);

                        newBody.Add(tempBody);
                        mainDocument.MainDocumentPart.Document.Body = new Body(newBody.ToString());
                        mainDocument.MainDocumentPart.Document.Save();
                        mainDocument.Package.Flush();
                    }
                }
            }
            catch (OpenXmlPackageException oxmle)
            {
                throw new OfficeMergeControlException(string.Format(CultureInfo.CurrentCulture, "Error while merging files. Document index {0}", pointer), oxmle);
            }
            catch (Exception e)
            {
                throw new OfficeMergeControlException(string.Format(CultureInfo.CurrentCulture, "Error while merging files. Document index {0}", pointer), e);
            }
            finally
            {
                ret = mainStream.ToArray();
                mainStream.Close();
                mainStream.Dispose();
            }
            return (ret);
        }
    }
}

我希望这可以帮助你.


@MadBoy - 它不会在合并文档之间显式创建新的分页符,它只会根据需要流过新页面.但是,您可以通过执行以下操作(在for循环中的第一行之前)显式地在文档之间添加分页符:`newBody.Add(XElement.Parse(new Paragraph(new Run(new Break {Type = BreakValues.Page})). OuterXml));`

2> Rob Windsor..:

您不需要使用自动化.DOCX文件基于OpenXML格式.它们只是zip文件,里面有一堆XML和二进制部分(思考文件).您可以使用Packaging API(WindowsBase.dll中的System.IO.Packaging)打开它们,并使用Framework中的任何XML类对它们进行操作.

查看OpenXMLDeveloper.org了解详细信息.


自动化来自撒旦.好的答案,Rob.

3> Mike B..:

这是一个非常晚的原始问题,并且有很多变化,但我想我会分享我编写合并逻辑的方式.这使用了Open XML Power Tools

public byte[] CreateDocument(IList documentsToMerge)
{
    List documentBuilderSources = new List();
    foreach (byte[] documentByteArray in documentsToMerge)
    {
        documentBuilderSources.Add(new Source(new WmlDocument(string.Empty, documentByteArray), false));
    }

    WmlDocument mergedDocument = DocumentBuilder.BuildDocument(documentBuilderSources);
    return mergedDocument.DocumentByteArray;
}

目前,这在我们的应用程序中运行良好.我稍微更改了代码,因为我的要求是每个需要首先处理的文档.所以传入的是具有模板字节数组的DTO对象以及需要替换的各种值.这是我的代码目前的样子.这使得代码更进一步.

public byte[] CreateDocument(IList documentTemplates)
{
    List documentBuilderSources = new List();
    foreach (DocumentSection documentTemplate in documentTemplates.OrderBy(dt => dt.Rank))
    {
        // Take the template replace the items and then push it into the chunk
        using (MemoryStream templateStream = new MemoryStream())
        {
            templateStream.Write(documentTemplate.Template, 0, documentTemplate.Template.Length);

            this.ProcessOpenXMLDocument(templateStream, documentTemplate.Fields);

            documentBuilderSources.Add(new Source(new WmlDocument(string.Empty, templateStream.ToArray()), false));
        }
    }

    WmlDocument mergedDocument = DocumentBuilder.BuildDocument(documentBuilderSources);
    return mergedDocument.DocumentByteArray;
}

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有