C# 将多个word文档合并到一个打开的Xml中

C# 将多个word文档合并到一个打开的Xml中,c#,merge,openxml,docx,openxml-sdk,C#,Merge,Openxml,Docx,Openxml Sdk,我有大约10个word文档,它们是使用开放xml和其他东西生成的。 现在我想创建另一个word文档,我想一个接一个地将它们加入到这个新创建的文档中。 我希望使用开放式xml,任何提示都很有用。 下面是我的代码: private void CreateSampleWordDocument() { //string sourceFile = Path.Combine("D:\\GeneralLetter.dot"); //string destination

我有大约10个word文档,它们是使用开放xml和其他东西生成的。 现在我想创建另一个word文档,我想一个接一个地将它们加入到这个新创建的文档中。 我希望使用开放式xml,任何提示都很有用。 下面是我的代码:

 private void CreateSampleWordDocument()
    {
        //string sourceFile = Path.Combine("D:\\GeneralLetter.dot");
        //string destinationFile = Path.Combine("D:\\New.doc");
        string sourceFile = Path.Combine("D:\\GeneralWelcomeLetter.docx");
        string destinationFile = Path.Combine("D:\\New.docx");
        try
        {
            // Create a copy of the template file and open the copy
            //File.Copy(sourceFile, destinationFile, true);
            using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFile, true))
            {
                // Change the document type to Document
                document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
                //Get the Main Part of the document
                MainDocumentPart mainPart = document.MainDocumentPart;
                mainPart.Document.Save();
            }
        }
        catch
        {
        }
    }
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
更新(使用altchunk):

using (WordprocessingDocument myDoc = WordprocessingDocument.Open("D:\\Test.docx", true))
        {
            string altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString().Substring(0, 2) ;
            MainDocumentPart mainPart = myDoc.MainDocumentPart;
            AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
                AlternativeFormatImportPartType.WordprocessingML, altChunkId);
            using (FileStream fileStream = File.Open("D:\\Test1.docx", FileMode.Open))
                chunk.FeedData(fileStream);
            AltChunk altChunk = new AltChunk();
            altChunk.Id = altChunkId;
            mainPart.Document
                .Body
                .InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
            mainPart.Document.Save();
        } 
 using (WordprocessingDocument myDoc = WordprocessingDocument.Open("D:\\Test.docx", true))
        {

            MainDocumentPart mainPart = myDoc.MainDocumentPart;
            string altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString().Substring(0, 3);
            AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId);
            using (FileStream fileStream = File.Open("d:\\Test1.docx", FileMode.Open))
            {
                chunk.FeedData(fileStream);
                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;
                mainPart.Document
                    .Body
                    .InsertAfter(altChunk, mainPart.Document.Body
                    .Elements<Paragraph>().Last());
                mainPart.Document.Save();
            }
            using (FileStream fileStream = File.Open("d:\\Test2.docx", FileMode.Open))
            {
                chunk.FeedData(fileStream);
                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;
                mainPart.Document
                    .Body
                    .InsertAfter(altChunk, mainPart.Document.Body
                    .Elements<Paragraph>().Last());
            }
            using (FileStream fileStream = File.Open("d:\\Test3.docx", FileMode.Open))
            {
                chunk.FeedData(fileStream);
                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;
                mainPart.Document
                    .Body
                    .InsertAfter(altChunk, mainPart.Document.Body
                    .Elements<Paragraph>().Last());
            } 
        }
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
而不是:

Test
Test1
Test2
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);

OpenXML周围有一个很好的包装器API(DocumentBuilder2.2),专门设计用于合并文档,具有选择要合并的段落等灵活性。您可以从(更新:移动到)下载它

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
关于如何使用它的文档和屏幕显示是

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
更新:代码示例

 var sources = new List<Source>();
 //Document Streams (File Streams) of the documents to be merged.
 foreach (var stream in documentstreams)
 {
        var tempms = new MemoryStream();
        stream.CopyTo(tempms);
        sources.Add(new Source(new WmlDocument(stream.Length.ToString(), tempms), true));
 }

  var mergedDoc = DocumentBuilder.BuildDocument(sources);
  mergedDoc.SaveAs(@"C:\TargetFilePath");
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
在合并文档的
AltChunk
documentbuilder
方法之间找到了这一点-有助于根据需求进行选择

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
您也可以使用库来合并文档,但我更喜欢使用文档生成器来合并文档

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);

希望这有帮助。

仅使用OpenXMLSDK,您可以使用元素将多个文档合并为一个文档

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
此链接和此链接提供了一些示例

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
编辑1

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
根据您在更新的问题(更新#1)中使用
altchunk
的代码,下面是我测试过的VB.Net代码,它对我来说非常有用:

Using myDoc = DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Open("D:\\Test.docx", True)
        Dim altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString().Substring(0, 2)
        Dim mainPart = myDoc.MainDocumentPart
        Dim chunk = mainPart.AddAlternativeFormatImportPart(
            DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML, altChunkId)
        Using fileStream As IO.FileStream = IO.File.Open("D:\\Test1.docx", IO.FileMode.Open)
            chunk.FeedData(fileStream)
        End Using
        Dim altChunk = New DocumentFormat.OpenXml.Wordprocessing.AltChunk()
        altChunk.Id = altChunkId
        mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements(Of DocumentFormat.OpenXml.Wordprocessing.Paragraph).Last())
        mainPart.Document.Save()
End Using
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
编辑2

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
第二期(更新2)

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
此代码将两次附加Test2数据,以代替Test1数据 嗯

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
altchunkid
相关

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
对于要合并到主文档中的每个文档,您需要:

AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
string altchunkid = mainPart.GetIdOfPart(chunk);
  • main documentpart
    中添加一个
    AlternativeFormatImportPart
    ,其Id必须是唯一的。此元素包含插入的数据
  • 在正文中添加一个
    Altchunk
    元素,在该元素中设置
    id
    以引用前面的
    AlternativeFormatImportPart
  • 在代码中,所有的
    altchunk
    都使用相同的Id。这就是为什么你会多次看到相同的文本

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);
    
    我不确定altchunkid在您的代码中是否唯一:
    string altchunkid=“altchunkid”+DateTime.Now.Ticks.ToString()子字符串(0,2)

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);
    
    如果您不需要设置特定值,我建议您在添加
    AlternativeFormatImportPart
    时不要显式设置
    AltChunkId
    。相反,您会得到由SDK生成的一个,如下所示:

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);
    
    VB.Net

    Dim chunk As AlternativeFormatImportPart = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML)
    Dim altchunkid As String = mainPart.GetIdOfPart(chunk)
    
    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);
    
    #

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);
    
    在C#中易于使用:

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);
    
    使用系统;
    使用System.IO;
    使用System.Linq;
    使用DocumentFormat.OpenXml.Packaging;
    使用DocumentFormat.OpenXml.Wordprocessing;
    命名空间WordMergeProject
    {
    公共课程
    {
    私有静态void Main(字符串[]args)
    {
    byte[]word1=File.ReadAllBytes(@.\..\word1.docx”);
    byte[]word2=File.ReadAllBytes(@.\..\word2.docx”);
    字节[]结果=合并(字1,字2);
    文件.writealBytes(@.\..\word3.docx),结果;
    }
    专用静态字节[]合并(字节[]dest,字节[]src)
    {
    字符串altChunkId=“altChunkId”+DateTime.Now.Ticks.ToString();
    var memoryStreamDest=新的MemoryStream();
    MemoryStream dest.Write(dest,0,dest.Length);
    memoryStreamDest.Seek(0,SeekOrigin.Begin);
    var MemoryStream src=新的MemoryStream(src);
    使用(WordprocessingDocument doc=WordprocessingDocument.Open(memoryStreamDest,true))
    {
    MainDocumentPart mainPart=doc.MainDocumentPart;
    替代格式导入部分替代部分=
    mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML,altChunkId);
    altPart.FeedData(memoryStreamSrc);
    var altChunk=new altChunk();
    altChunk.Id=altChunkId;
    openxmlement lastElem=mainPart.Document.Body.Elements().LastOrDefault();
    if(lastElem==null)
    {
    lastElem=mainPart.Document.Body.Elements().Last();
    }
    //佩奇·艾因弗根
    段落pageBreakP=新段落();
    运行PageBreaker=新运行();
    Break pageBreakBr=newbreak(){Type=BreakValues.Page};
    pageBreakP.Append(pagebreaker);
    pagebreaker.Append(pageBreakBr);
    返回memoryStreamDest.ToArray();
    }
    }
    }
    
    这些答案中唯一缺少的是
    for
    循环

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);
    
    对于那些只想复制/粘贴的用户:

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);
    
    void MergeInNewFile(string resultFile, IList<string> filenames)
    {
        using (WordprocessingDocument document = WordprocessingDocument.Create(resultFile, WordprocessingDocumentType.Document))
        {
            MainDocumentPart mainPart = document.AddMainDocumentPart();
            mainPart.Document = new Document(new Body());
    
            foreach (string filename in filenames)
            {
                AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML);
                string altChunkId = mainPart.GetIdOfPart(chunk);
    
                using (FileStream fileStream = File.Open(filename, FileMode.Open))
                {
                    chunk.FeedData(fileStream);
                }
    
                AltChunk altChunk = new AltChunk { Id = altChunkId };
                mainPart.Document.Body.AppendChild(altChunk);
            }
    
            mainPart.Document.Save();
        }
    }
    
    void merginnewfile(字符串结果文件、IList文件名)
    {
    使用(WordprocessingDocument文档=WordprocessingDocument.Create(结果文件,WordprocessingDocumentType.document))
    {
    MainDocumentPart mainPart=document.AddMainDocumentPart();
    mainPart.Document=新文档(新主体());
    foreach(文件名中的字符串文件名)
    {
    AlternativeFormatImportPart chunk=mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML);
    string altChunkId=mainPart.GetIdOfPart(chunk);
    使用(FileStream FileStream=File.Open(filename,FileMode.Open))
    {
    FeedData(fileStream);
    }
    AltChunk AltChunk=新的AltChunk{Id=AltChunk Id};
    mainPart.Document.Body.AppendChild(altChunk);
    }
    mainPart.Document.Save();
    }
    }
    

    所有的功劳都归Chris和yonexbat所有

    在OpenXml中有没有一种方法可以通过编码来实现,因为这项任务真的很折磨我,我不能使用任何其他工具等。这些库都是围绕OpenXml的开源包装。Document Builder使用OpenXml sdk进行合并,没有硬依赖关系。合并文档也不是一项简单的任务内容丰富
    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML);
    string altchunkid = mainPart.GetIdOfPart(chunk);