使用C#實現(xiàn)輕松合并多份Word
很多項目需要把多份 Word 文檔匯總到一份成品里:例如把多個章節(jié)的材料拼成一個報告、把不同來源的稿件合并后交付。與此同時,“合并后格式是否正常、分頁是否符合預(yù)期、代碼是否足夠簡潔”往往決定了方案能否落地。
下面介紹兩種常見的合并策略,均使用 Spire.Doc for .NET 實現(xiàn):
- 方法一 :將后文檔整體追加到前文檔后面(通常帶來“從新頁開始”的整體插入體驗)
- 方法二 :遍歷后文檔的 Section,將其內(nèi)容對象克隆后追加到前文檔最后一個 Section,適合更精細的結(jié)構(gòu)控制
Spire.Doc 用途與安裝方法(Section 簡介)
Spire.Doc 是用于 .NET 讀取、編輯與生成 Word 文檔(DOC/DOCX)的組件庫。它提供面向文檔結(jié)構(gòu)的 API,例如加載文檔、插入內(nèi)容、遍歷 Section/Body/對象集合、復(fù)制文檔元素、保存為 DOCX 等。相比自行解析 docx 壓縮包與 XML,使用它可以顯著降低開發(fā)成本。
安裝方式(推薦 NuGet):
- 在 Visual Studio 打開項目
- 右鍵項目 → 管理 NuGet 程序包
- 搜索并安裝 Spire.Doc for .NET
- 在代碼中引用命名空間:
using Spire.Doc;
完成安裝后,就能直接通過 Document 類來加載與操作 Word 文件。
方法一:整體插入到末尾(從新頁開始的常見效果)
當(dāng)目標(biāo)是“把 Doc2 作為一個整體接到 Doc1 后面”,同時希望合并結(jié)果更接近 Word 中的“插入文檔/追加內(nèi)容”的直觀體驗時,可以使用 InsertTextFromFile。
實現(xiàn)思路:
- 創(chuàng)建
Document對象作為承載文檔 - 加載主文檔(Doc1)
- 將另一個 Word 文件(Doc2)插入到主文檔后
- 保存為新的合并文件
示例代碼:
using Spire.Doc;
namespace MergeWord
{
class Program
{
static void Main(string[] args)
{
// Create a Document instance
Document document = new Document();
// Load the original Word document
document.LoadFromFile("Doc1.docx", FileFormat.Docx);
// Insert another Word document entirely to the original document
document.InsertTextFromFile("Doc2.docx", FileFormat.Docx);
// Save the result document
document.SaveToFile("MergedWord.docx", FileFormat.Docx);
}
}
}
這種方式的特點
- 代碼量少、開發(fā)速度快
- 更偏“整體追加”,適合按文檔邊界合并
- 對 Section 級別結(jié)構(gòu)的細節(jié)控制相對少,但通常足夠滿足常見匯總需求
方法二:追加到第一個文檔最后一個 Section(結(jié)構(gòu)更可控)
如果合并要求更精細,例如盡量讓內(nèi)容與前文檔“同節(jié)連續(xù)”,或者需要把后文檔的內(nèi)容對象逐個追加到前文檔末尾,那么可采用第二種方案:遍歷后文檔的 Sections,再遍歷每個 Section 的 Body.ChildObjects,將對象 Clone() 后加入前文檔最后一個 Section。
實現(xiàn)思路:
- 分別加載
doc1與doc2 - 遍歷
doc2.Sections - 對每個 section,遍歷其
section.Body.ChildObjects - 將克隆后的對象添加到
doc1.LastSection.Body.ChildObjects - 保存
doc1作為合并結(jié)果
示例代碼:
using Spire.Doc;
namespace MergeWord
{
class Program
{
static void Main(string[] args)
{
// Load two Word documents
Document doc1 = new Document("Doc1.docx");
Document doc2 = new Document("Doc2.docx");
// Loop through the second document to get all the sections
foreach (Section section in doc2.Sections)
{
// Loop through the sections of the second document to get their child objects
foreach (DocumentObject obj in section.Body.ChildObjects)
{
// Get the last section of the first document
Section lastSection = doc1.LastSection;
// Add all child objects to the last section of the first document
lastSection.Body.ChildObjects.Add(obj.Clone());
}
}
// Save the result document
doc1.SaveToFile("MergeDocuments.docx", FileFormat.Docx);
}
}
}
這種方式的特點
- 更接近“把內(nèi)容對象直接拼到最后一節(jié)里”
- 通過
Clone()進行對象復(fù)制,避免直接引用引發(fā)的問題 - 適合處理包含多節(jié)結(jié)構(gòu)、頁眉頁腳/分頁規(guī)則等更復(fù)雜情況(具體效果仍需根據(jù)模板而定)
如何選擇
- 只想快速合并,并希望結(jié)果接近“從新頁開始追加”的直觀效果:方法一更省事。
- 需要更強的結(jié)構(gòu)控制,把后文檔內(nèi)容追加到前文檔最后一個 Section:方法二更貼合需求。
如果你的文檔模板包含頁眉頁腳、不同方向頁面(橫/豎版)或復(fù)雜節(jié)配置,建議優(yōu)先用方法二做驗證;如果只是普通文本與表格拼接,方法一通常更快更穩(wěn)定。
需要的話,我也可以基于這兩種方法給出“分頁符/節(jié)屬性”可能導(dǎo)致的差異排查清單,幫助你在真實模板上快速定位合并后的格式問題。
知識擴展
在 C# 中合并 Word 文檔有多種實現(xiàn)方式,從完全免費的 OpenXML SDK 到 API 簡潔的 商業(yè)庫,各有優(yōu)劣。下表對比了幾種主流方案,方便你快速選型:
| 方案 | 是否免費 | 開發(fā)效率 | 代碼復(fù)雜度 | 特殊能力 | 適用場景 |
|---|---|---|---|---|---|
| OpenXML SDK | ? 免費 | 較低 | 高 | 需手動處理底層XML和分節(jié)符 | 零成本、有技術(shù)余力的項目 |
| DocX | ? 免費 | 中 | 中 | 不支持加密/舊版.doc文件 | 非商業(yè)個人項目或小規(guī)模免費場景 |
| Spire.Doc | ? 商業(yè)(免費版有限制) | 高 | 極低 | 支持所有Word格式、Document.AppendDocument()一行式分頁合并 | 快速開發(fā)、商業(yè)項目 |
| Aspose.Words | ? 商業(yè) | 高 | 極低 | 工業(yè)級穩(wěn)定、段落分頁控制、層次化結(jié)構(gòu)導(dǎo)入 | 高度格式保真、企業(yè)級應(yīng)用 |
| GroupDocs.Merger | ? 商業(yè) | 高 | 中 | 支持跨格式合并 (Word/PDF/PPT) | 多格式文檔處理平臺 |
Spire.Doc:最簡潔方案
代碼量極少,使用 Document.AppendDocument() 方法即可直接合并。
安裝:
Install-Package Spire.Doc
核心代碼:
using Spire.Doc;
Document doc = new Document("Document1.docx");
doc.AppendDocument(new Document("Document2.docx"), FileFormat.Docx2013);
doc.AppendDocument(new Document("Document3.docx"), FileFormat.Docx2013);
doc.SaveToFile("MergedDocument.docx", FileFormat.Docx2013);Aspose.Words:工業(yè)級方案
支持 段落分頁控制、精確分節(jié)管理,也能高效導(dǎo)入多個文檔。
安裝:
dotnet add package Aspose.Words
基礎(chǔ)合并:
using Aspose.Words;
Document mergedDoc = new Document("Doc1.docx");
mergedDoc.AppendDocument(new Document("Doc2.docx"), ImportFormatMode.KeepSourceFormatting);
mergedDoc.Save("Merged.docx");高級合并(逐頁追加、目標(biāo)文檔完整保留):
推薦使用 Document.AppendDocument()。同時為了規(guī)避 ASP.NET 的權(quán)限限制,商業(yè)開發(fā)也可考慮 MemoryStream 在內(nèi)存中合并多個文檔,確保格式和圖表不丟失。
using Aspose.Words;
Document mergedDoc = new Document();
var stream1 = new MemoryStream(File.ReadAllBytes("Doc1.docx"));
var stream2 = new MemoryStream(File.ReadAllBytes("Doc2.docx"));
mergedDoc.AppendDocument(new Document(stream1), ImportFormatMode.KeepSourceFormatting);
mergedDoc.AppendDocument(new Document(stream2), ImportFormatMode.KeepSourceFormatting);
mergedDoc.Save("Merged.docx");GroupDocs.Merger:跨格式方案
安裝:
dotnet add package GroupDocs.Merger
代碼示例:
using GroupDocs.Merger;
var merger = new Merger("Document1.docx");
merger.Join("Document2.docx");
merger.Join("Document3.docx");
merger.Save("MergedDocument.docx");OpenXML SDK:免費、強控底層
優(yōu)勢是完全免費且支持細粒度控制,但需手動處理分節(jié)符沖突。
安裝:
dotnet add package DocumentFormat.OpenXml
核心代碼(手動分頁):
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.IO;
using System.Linq;
using A = DocumentFormat.OpenXml;
public static void MergeWordDocuments(string outputPath, params string[] inputPaths)
{
using (WordprocessingDocument outputDoc = WordprocessingDocument.Create(outputPath, WordprocessingDocumentType.Document))
{
Body outputBody = outputDoc.MainDocumentPart.Document.Body;
outputBody.RemoveAllChildren();
bool isFirst = true;
foreach (string inputPath in inputPaths)
{
using (WordprocessingDocument inputDoc = WordprocessingDocument.Open(inputPath, false))
{
Body inputBody = inputDoc.MainDocumentPart.Document.Body;
foreach (var element in inputBody.Elements())
{
outputBody.AppendChild(element.CloneNode(true));
}
if (!isFirst)
{
outputBody.AppendChild(new Paragraph(new Run(new Break() { Type = BreakValues.Page })));
}
isFirst = false;
}
}
outputDoc.MainDocumentPart.Document.Save();
}
}關(guān)鍵注意事項
- 分頁符處理:免費方案 (OpenXML) 需手動在新文檔間插入
Break保證各文檔分頁獨立。 - 格式兼容性:
.doc舊格式需注意Spire.Doc與Aspose.Words支持較好;DocX不支持.doc格式。 - 許可證限制:免費版商業(yè)庫通常有水印、頁數(shù)限制,評估時務(wù)必先試用確認(rèn)。如 Free Spire.Doc 存在頁數(shù)限制。
- 內(nèi)存優(yōu)化:大量文檔合并時建議使用 流式處理 (MemoryStream),保證內(nèi)存穩(wěn)定。
提供更多 批量合并邏輯 或 服務(wù)器端部署細節(jié) 可定制方案。
到此這篇關(guān)于使用C#實現(xiàn)輕松合并多份Word的文章就介紹到這了,更多相關(guān)C#合并多個Word內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#獲取所有SQL Server數(shù)據(jù)庫名稱的方法
這篇文章主要介紹了C#獲取所有SQL Server數(shù)據(jù)庫名稱的方法,涉及C#針對sql server數(shù)據(jù)庫的簡單查詢技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08
C#使用Log4net實現(xiàn)將日志輸出到控制臺或者文本文檔
Log4net?是一個穩(wěn)定且功能豐富的日志庫,已經(jīng)存在多年并且被廣泛使用,這篇文章主要為大家介紹了如何使用Log4net實現(xiàn)將日志輸出到控制臺或者文本文檔,感興趣的可以了解下2024-03-03
C#導(dǎo)航器Xpath與XPathNavigator類
這篇文章介紹了C#導(dǎo)航器Xpath與XPathNavigator類,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06

