使用C#實(shí)現(xiàn)輕松合并多份Word
很多項(xiàng)目需要把多份 Word 文檔匯總到一份成品里:例如把多個(gè)章節(jié)的材料拼成一個(gè)報(bào)告、把不同來(lái)源的稿件合并后交付。與此同時(shí),“合并后格式是否正常、分頁(yè)是否符合預(yù)期、代碼是否足夠簡(jiǎn)潔”往往決定了方案能否落地。
下面介紹兩種常見(jiàn)的合并策略,均使用 Spire.Doc for .NET 實(shí)現(xiàn):
- 方法一 :將后文檔整體追加到前文檔后面(通常帶來(lái)“從新頁(yè)開始”的整體插入體驗(yàn))
- 方法二 :遍歷后文檔的 Section,將其內(nèi)容對(duì)象克隆后追加到前文檔最后一個(gè) Section,適合更精細(xì)的結(jié)構(gòu)控制
Spire.Doc 用途與安裝方法(Section 簡(jiǎn)介)
Spire.Doc 是用于 .NET 讀取、編輯與生成 Word 文檔(DOC/DOCX)的組件庫(kù)。它提供面向文檔結(jié)構(gòu)的 API,例如加載文檔、插入內(nèi)容、遍歷 Section/Body/對(duì)象集合、復(fù)制文檔元素、保存為 DOCX 等。相比自行解析 docx 壓縮包與 XML,使用它可以顯著降低開發(fā)成本。
安裝方式(推薦 NuGet):
- 在 Visual Studio 打開項(xiàng)目
- 右鍵項(xiàng)目 → 管理 NuGet 程序包
- 搜索并安裝 Spire.Doc for .NET
- 在代碼中引用命名空間:
using Spire.Doc;
完成安裝后,就能直接通過(guò) Document 類來(lái)加載與操作 Word 文件。
方法一:整體插入到末尾(從新頁(yè)開始的常見(jiàn)效果)
當(dāng)目標(biāo)是“把 Doc2 作為一個(gè)整體接到 Doc1 后面”,同時(shí)希望合并結(jié)果更接近 Word 中的“插入文檔/追加內(nèi)容”的直觀體驗(yàn)時(shí),可以使用 InsertTextFromFile。
實(shí)現(xiàn)思路:
- 創(chuàng)建
Document對(duì)象作為承載文檔 - 加載主文檔(Doc1)
- 將另一個(gè) 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);
}
}
}
這種方式的特點(diǎn)
- 代碼量少、開發(fā)速度快
- 更偏“整體追加”,適合按文檔邊界合并
- 對(duì) Section 級(jí)別結(jié)構(gòu)的細(xì)節(jié)控制相對(duì)少,但通常足夠滿足常見(jiàn)匯總需求
方法二:追加到第一個(gè)文檔最后一個(gè) Section(結(jié)構(gòu)更可控)
如果合并要求更精細(xì),例如盡量讓內(nèi)容與前文檔“同節(jié)連續(xù)”,或者需要把后文檔的內(nèi)容對(duì)象逐個(gè)追加到前文檔末尾,那么可采用第二種方案:遍歷后文檔的 Sections,再遍歷每個(gè) Section 的 Body.ChildObjects,將對(duì)象 Clone() 后加入前文檔最后一個(gè) Section。
實(shí)現(xiàn)思路:
- 分別加載
doc1與doc2 - 遍歷
doc2.Sections - 對(duì)每個(gè) section,遍歷其
section.Body.ChildObjects - 將克隆后的對(duì)象添加到
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);
}
}
}
這種方式的特點(diǎn)
- 更接近“把內(nèi)容對(duì)象直接拼到最后一節(jié)里”
- 通過(guò)
Clone()進(jìn)行對(duì)象復(fù)制,避免直接引用引發(fā)的問(wèn)題 - 適合處理包含多節(jié)結(jié)構(gòu)、頁(yè)眉頁(yè)腳/分頁(yè)規(guī)則等更復(fù)雜情況(具體效果仍需根據(jù)模板而定)
如何選擇
- 只想快速合并,并希望結(jié)果接近“從新頁(yè)開始追加”的直觀效果:方法一更省事。
- 需要更強(qiáng)的結(jié)構(gòu)控制,把后文檔內(nèi)容追加到前文檔最后一個(gè) Section:方法二更貼合需求。
如果你的文檔模板包含頁(yè)眉頁(yè)腳、不同方向頁(yè)面(橫/豎版)或復(fù)雜節(jié)配置,建議優(yōu)先用方法二做驗(yàn)證;如果只是普通文本與表格拼接,方法一通常更快更穩(wěn)定。
需要的話,我也可以基于這兩種方法給出“分頁(yè)符/節(jié)屬性”可能導(dǎo)致的差異排查清單,幫助你在真實(shí)模板上快速定位合并后的格式問(wèn)題。
知識(shí)擴(kuò)展
在 C# 中合并 Word 文檔有多種實(shí)現(xiàn)方式,從完全免費(fèi)的 OpenXML SDK 到 API 簡(jiǎn)潔的 商業(yè)庫(kù),各有優(yōu)劣。下表對(duì)比了幾種主流方案,方便你快速選型:
| 方案 | 是否免費(fèi) | 開發(fā)效率 | 代碼復(fù)雜度 | 特殊能力 | 適用場(chǎng)景 |
|---|---|---|---|---|---|
| OpenXML SDK | ? 免費(fèi) | 較低 | 高 | 需手動(dòng)處理底層X(jué)ML和分節(jié)符 | 零成本、有技術(shù)余力的項(xiàng)目 |
| DocX | ? 免費(fèi) | 中 | 中 | 不支持加密/舊版.doc文件 | 非商業(yè)個(gè)人項(xiàng)目或小規(guī)模免費(fèi)場(chǎng)景 |
| Spire.Doc | ? 商業(yè)(免費(fèi)版有限制) | 高 | 極低 | 支持所有Word格式、Document.AppendDocument()一行式分頁(yè)合并 | 快速開發(fā)、商業(yè)項(xiàng)目 |
| Aspose.Words | ? 商業(yè) | 高 | 極低 | 工業(yè)級(jí)穩(wěn)定、段落分頁(yè)控制、層次化結(jié)構(gòu)導(dǎo)入 | 高度格式保真、企業(yè)級(jí)應(yīng)用 |
| GroupDocs.Merger | ? 商業(yè) | 高 | 中 | 支持跨格式合并 (Word/PDF/PPT) | 多格式文檔處理平臺(tái) |
Spire.Doc:最簡(jiǎn)潔方案
代碼量極少,使用 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è)級(jí)方案
支持 段落分頁(yè)控制、精確分節(jié)管理,也能高效導(dǎo)入多個(gè)文檔。
安裝:
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");高級(jí)合并(逐頁(yè)追加、目標(biāo)文檔完整保留):
推薦使用 Document.AppendDocument()。同時(shí)為了規(guī)避 ASP.NET 的權(quán)限限制,商業(yè)開發(fā)也可考慮 MemoryStream 在內(nèi)存中合并多個(gè)文檔,確保格式和圖表不丟失。
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:免費(fèi)、強(qiáng)控底層
優(yōu)勢(shì)是完全免費(fèi)且支持細(xì)粒度控制,但需手動(dòng)處理分節(jié)符沖突。
安裝:
dotnet add package DocumentFormat.OpenXml
核心代碼(手動(dòng)分頁(yè)):
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)鍵注意事項(xiàng)
- 分頁(yè)符處理:免費(fèi)方案 (OpenXML) 需手動(dòng)在新文檔間插入
Break保證各文檔分頁(yè)獨(dú)立。 - 格式兼容性:
.doc舊格式需注意Spire.Doc與Aspose.Words支持較好;DocX不支持.doc格式。 - 許可證限制:免費(fèi)版商業(yè)庫(kù)通常有水印、頁(yè)數(shù)限制,評(píng)估時(shí)務(wù)必先試用確認(rèn)。如 Free Spire.Doc 存在頁(yè)數(shù)限制。
- 內(nèi)存優(yōu)化:大量文檔合并時(shí)建議使用 流式處理 (MemoryStream),保證內(nèi)存穩(wěn)定。
提供更多 批量合并邏輯 或 服務(wù)器端部署細(xì)節(jié) 可定制方案。
到此這篇關(guān)于使用C#實(shí)現(xiàn)輕松合并多份Word的文章就介紹到這了,更多相關(guān)C#合并多個(gè)Word內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#獲取所有SQL Server數(shù)據(jù)庫(kù)名稱的方法
這篇文章主要介紹了C#獲取所有SQL Server數(shù)據(jù)庫(kù)名稱的方法,涉及C#針對(duì)sql server數(shù)據(jù)庫(kù)的簡(jiǎn)單查詢技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08
C#查找素?cái)?shù)實(shí)現(xiàn)方法
這篇文章主要介紹了C#查找素?cái)?shù)實(shí)現(xiàn)方法,程序中有很多使用的功能模塊,非常適合C#初學(xué)者學(xué)習(xí)借鑒,需要的朋友可以參考下2014-08-08
C#使用Log4net實(shí)現(xiàn)將日志輸出到控制臺(tái)或者文本文檔
Log4net?是一個(gè)穩(wěn)定且功能豐富的日志庫(kù),已經(jīng)存在多年并且被廣泛使用,這篇文章主要為大家介紹了如何使用Log4net實(shí)現(xiàn)將日志輸出到控制臺(tái)或者文本文檔,感興趣的可以了解下2024-03-03
C#導(dǎo)航器Xpath與XPathNavigator類
這篇文章介紹了C#導(dǎo)航器Xpath與XPathNavigator類,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06

