使用OpenXmlPowerTools DocumentBuilder合并文档如何实现分页?
DOCX合并:让第二个文档从新页开始并保留格式
问题背景
使用OpenXmlPowerTools的DocumentBuilder合并DOCX文档时,第二个文档直接追加在第一个文档末尾,需要实现新页分隔;尝试Open XML原生AltChunk方式会导致第二个文档格式丢失。
原合并代码
public void DocMerger() { var source1 = Server.MapPath(Url.Content("~/1.docx")); //source 1 var source2 = Server.MapPath(Url.Content("~/2.docx")); //source 2 var merged = Server.MapPath(Url.Content("~/App_Data/merged.docx")); //merged var f1 = new FileInfo(source1); var f2 = new FileInfo(source2); //Use DocumentBuilder and merge the files var sources = new List<OpenXmlPowerTools.Source>() { new Source(new WmlDocument(f1.FullName),true), new Source(new WmlDocument(f2.FullName),true), }; var mergedDocument = DocumentBuilder.BuildDocument(sources); mergedDocument.SaveAs(merged); //save merged data as merged.docx }
尝试过的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(); }
可行解决方案
以下两种方案均基于OpenXmlPowerTools合并逻辑,可完整保留原文档格式,实现新页分隔:
方案1:在第一个文档末尾添加分页符
合并前修改第一个文档,在其Body末尾插入带有分页属性的段落,强制后续内容从新页开始:
public void DocMerger() { var source1 = Server.MapPath(Url.Content("~/1.docx")); var source2 = Server.MapPath(Url.Content("~/2.docx")); var merged = Server.MapPath(Url.Content("~/App_Data/merged.docx")); // 加载第一个文档并添加分页符 var doc1 = new WmlDocument(source1); using (var memoryStream = new MemoryStream()) { doc1.WriteToStream(memoryStream); using (var wordDoc = WordprocessingDocument.Open(memoryStream, true)) { var body = wordDoc.MainDocumentPart.Document.Body; // 创建带分页符的段落 var pageBreakPara = new Paragraph( new ParagraphProperties( new SectionProperties( new PageBreakBefore() ) ) ); body.Append(pageBreakPara); wordDoc.Save(); } doc1 = new WmlDocument(memoryStream); } // 执行合并 var sources = new List<OpenXmlPowerTools.Source>() { new Source(doc1, true), new Source(new WmlDocument(source2), true), }; var mergedDocument = DocumentBuilder.BuildDocument(sources); mergedDocument.SaveAs(merged); }
方案2:在第二个文档开头添加分页符
若不想修改第一个文档,可在第二个文档的起始位置插入分页段落:
public void DocMerger() { var source1 = Server.MapPath(Url.Content("~/1.docx")); var source2 = Server.MapPath(Url.Content("~/2.docx")); var merged = Server.MapPath(Url.Content("~/App_Data/merged.docx")); // 加载第二个文档并在开头添加分页符 var doc2 = new WmlDocument(source2); using (var memoryStream = new MemoryStream()) { doc2.WriteToStream(memoryStream); using (var wordDoc = WordprocessingDocument.Open(memoryStream, true)) { var body = wordDoc.MainDocumentPart.Document.Body; // 创建带分页符的段落并插入到最前面 var pageBreakPara = new Paragraph( new ParagraphProperties( new SectionProperties( new PageBreakBefore() ) ) ); body.InsertAt(pageBreakPara, 0); wordDoc.Save(); } doc2 = new WmlDocument(memoryStream); } // 执行合并 var sources = new List<OpenXmlPowerTools.Source>() { new Source(new WmlDocument(source1), true), new Source(doc2, true), }; var mergedDocument = DocumentBuilder.BuildDocument(sources); mergedDocument.SaveAs(merged); }
方案说明
- 两种方案都通过
PageBreakBefore属性实现强制分页,完全基于OpenXmlPowerTools的合并逻辑,避免AltChunk的格式丢失问题 - 可根据实际需求选择修改第一个或第二个文档的方式
内容的提问来源于stack exchange,提问作者Rams
相关产品推荐
相关产品推荐

