C#調(diào)用OpenXml合并word文檔中的表格單元格
OpenXml合并word文檔的表格單元格主要依靠單元格TabelCell的TableCellProperties的HorizontalMerge和 VerticalMerge這兩個關(guān)鍵屬性,HorizontalMerge用于水平方向的單元格合并,VerticalMerge用于垂直方向的單元格合并,它們都使用MergedCellValues枚舉值,其中MergedCellValues.Restart表示開始合并,MergedCellValues.Continue表示被合并。
合并單元格主要由標(biāo)記為Restart的起始單元格和一個或多個標(biāo)記為Continue的后續(xù)單元格組成,起始單元格是合并區(qū)域的第一個單元格,該單元格的TableCellProperties的HorizontalMerge或VerticalMerge屬性值為Restart,起始單元格之后的所有單元格都使用Continue 值,表明它們屬于前一個起始單元格
以省份景點(diǎn)統(tǒng)計(jì)為例,將同一省份的景點(diǎn)數(shù)據(jù)相鄰顯示,超過一行則將省份名稱單元格合并,然后緊接一行計(jì)算同一省份的景點(diǎn)票價(jià)合計(jì)費(fèi)用,主要代碼、統(tǒng)計(jì)表格模板及統(tǒng)計(jì)表格數(shù)據(jù)如下所示:
int startRowIndex = 2;
int lineIndex = 0;
ScenicSpot rowData = null;
var totalRows = targetTable.Elements<TableRow>();
TableRow curRow = null;
IEnumerable<TableCell> cells = null;
foreach ( var records in m_lstScenicSpot.GroupBy(r=>r.Location))
{
int dataCount = records.Count();
decimal sum = records.Sum(r => r.TicketPrice);
foreach (var record in records)
{
curRow = totalRows.ElementAt(startRowIndex + lineIndex);
cells = curRow.Elements<TableCell>();
FillTabelCellData(cells.ElementAt(0), Convert.ToString(lineIndex + 1));
FillTabelCellData(cells.ElementAt(1), record.Location);
FillTabelCellData(cells.ElementAt(2), record.Name);
FillTabelCellData(cells.ElementAt(3), Convert.ToString(record.TicketPrice));
FillTabelCellData(cells.ElementAt(4), record.Description);
lineIndex++;
}
if (dataCount > 1)
{
MergeCellsVertically(totalRows.ToList(), 1, startRowIndex + lineIndex - dataCount, startRowIndex + lineIndex);
}
curRow = totalRows.ElementAt(startRowIndex + lineIndex);
cells = curRow.Elements<TableCell>();
FillTabelCellData(cells.ElementAt(0), "票價(jià)合計(jì)");
FillTabelCellData(cells.ElementAt(3), sum.ToString());
MergeCellsHorizontally(curRow, 0, 2);
lineIndex++;
}
/// <summary>
/// 水平合并同一行內(nèi)的連續(xù)單元格
/// </summary>
/// <param name="row">目標(biāo)行</param>
/// <param name="startColumnIndex">起始列索引</param>
/// <param name="endColumnIndex">結(jié)束列索引</param>
private static void MergeCellsHorizontally(TableRow row, int startColumnIndex, int endColumnIndex)
{
// 獲取該行所有單元格
var cells = row.Elements<TableCell>().ToList();
// 確保起始索引有效,并且起始索引小于結(jié)束索引
if (startColumnIndex < cells.Count && startColumnIndex < endColumnIndex)
{
TableCellProperties startCellProps = cells[startColumnIndex].GetFirstChild<TableCellProperties>() ?? new TableCellProperties();
startCellProps.HorizontalMerge = new HorizontalMerge { Val = MergedCellValues.Restart };
for (int i = startColumnIndex + 1; i <= endColumnIndex; i++)
{
var currentCell = cells.ElementAt(i);
TableCellProperties cellProps = currentCell.GetFirstChild<TableCellProperties>() ?? new TableCellProperties();
cellProps.HorizontalMerge = new HorizontalMerge { Val = MergedCellValues.Continue };
}
}
}
/// <summary>
/// 垂直合并不同行的同一列單元格
/// </summary>
/// <param name="rows">表格行集合</param>
/// <param name="columnIndex">要合并的列索引</param>
/// <param name="startRowIndex">起始行索引</param>
/// <param name="endRowIndex">結(jié)束行索引</param>
private static void MergeCellsVertically(List<TableRow> rows, int columnIndex, int startRowIndex, int endRowIndex)
{
// 確保行索引有效
if (startRowIndex < rows.Count && endRowIndex < rows.Count && startRowIndex <= endRowIndex)
{
// 獲取起始行的目標(biāo)單元格
var startRowCells = rows[startRowIndex].Elements<TableCell>().ToList();
// 獲取結(jié)束行的目標(biāo)單元格
var endRowCells = rows[endRowIndex].Elements<TableCell>().ToList();
if (columnIndex < startRowCells.Count && columnIndex < endRowCells.Count)
{
TableCellProperties startCellProps = startRowCells[columnIndex].GetFirstChild<TableCellProperties>() ?? new TableCellProperties();
startCellProps.VerticalMerge = new VerticalMerge { Val = MergedCellValues.Restart };
// 在被合并的后續(xù)單元格設(shè)置 VerticalMerge
for (int i = startRowIndex + 1; i <= endRowIndex; i++)
{
var currentRowCells = rows[i].Elements<TableCell>().ToList();
if (columnIndex < currentRowCells.Count)
{
TableCellProperties mergeCellProps = currentRowCells[columnIndex].GetFirstChild<TableCellProperties>() ?? new TableCellProperties();
// 設(shè)置 VerticalMerge 屬性,值為Continue 表示這是垂直合并的一部分
mergeCellProps.VerticalMerge = new VerticalMerge { Val = MergedCellValues.Continue };
}
}
}
}
}
結(jié)果如下

方法補(bǔ)充:
1.C#合并多個WORD文檔
文中提供了兩種合并:一是復(fù)制合并;一是插入合并,即將多個文檔按照先后順序合并到另一個文檔中。
調(diào)用方法:
string templatePathAll="填充模板.doc";//一般是一個空文檔 string filesPath="需合并的文檔目錄";//一個文件夾目錄,里面是需要合并的文檔 string Path="保存文檔.doc";//輸出文檔路徑 WordDocumentMerger wordDocMerger = new WordDocumentMerger(); wordDocMerger.InsertMerge(templatePathAll, filesPath, Path);
代碼如下:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Interop.Word;
using System.Reflection;
using System.IO;
using System.Diagnostics;
namespace Eipsoft.Common
{
///
/// Word文檔合并類
///
public class WordDocumentMerger
{
private ApplicationClass objApp = null;
private Document objDocLast = null;
private Document objDocBeforeLast = null;
public WordDocumentMerger()
{
objApp = new ApplicationClass();
}
#region 打開文件
private void Open(string tempDoc)
{
object objTempDoc = tempDoc;
object objMissing = System.Reflection.Missing.Value;
objDocLast = objApp.Documents.Open(
ref objTempDoc, //FileName
ref objMissing, //ConfirmVersions
ref objMissing, //ReadOnly
ref objMissing, //AddToRecentFiles
ref objMissing, //PasswordDocument
ref objMissing, //PasswordTemplate
ref objMissing, //Revert
ref objMissing, //WritePasswordDocument
ref objMissing, //WritePasswordTemplate
ref objMissing, //Format
ref objMissing, //Enconding
ref objMissing, //Visible
ref objMissing, //OpenAndRepair
ref objMissing, //DocumentDirection
ref objMissing, //NoEncodingDialog
ref objMissing //XMLTransform
);
objDocLast.Activate();
objDocLast.SpellingChecked = false;//關(guān)閉Word的拼寫檢查
objDocLast.ShowSpellingErrors = false;//關(guān)閉Word的拼寫錯誤提示
}
#endregion
#region 保存文件到輸出模板
private void SaveAs(string outDoc)
{
object objMissing = System.Reflection.Missing.Value;
object objOutDoc = outDoc;
objDocLast.SaveAs(
ref objOutDoc, //FileName
ref objMissing, //FileFormat
ref objMissing, //LockComments
ref objMissing, //PassWord
ref objMissing, //AddToRecentFiles
ref objMissing, //WritePassword
ref objMissing, //ReadOnlyRecommended
ref objMissing, //EmbedTrueTypeFonts
ref objMissing, //SaveNativePictureFormat
ref objMissing, //SaveFormsData
ref objMissing, //SaveAsAOCELetter,
ref objMissing, //Encoding
ref objMissing, //InsertLineBreaks
ref objMissing, //AllowSubstitutions
ref objMissing, //LineEnding
ref objMissing //AddBiDiMarks
);
}
#endregion
#region 循環(huán)合并多個文件(復(fù)制合并重復(fù)的文件)
///
/// 循環(huán)合并多個文件(復(fù)制合并重復(fù)的文件)
///
/// 模板文件
/// 需要合并的文件
/// 合并后的輸出文件
public void CopyMerge(string tempDoc, string[] arrCopies, string outDoc)
{
object objMissing = Missing.Value;
object objFalse = false;
object objTarget = WdMergeTarget.wdMergeTargetSelected;
object objUseFormatFrom = WdUseFormattingFrom.wdFormattingFromSelected;
try
{
//打開模板文件
Open(tempDoc);
foreach (string strCopy in arrCopies)
{
objDocLast.Merge(
strCopy, //FileName
ref objTarget, //MergeTarget
ref objMissing, //DetectFormatChanges
ref objUseFormatFrom, //UseFormattingFrom
ref objMissing //AddToRecentFiles
);
objDocBeforeLast = objDocLast;
objDocLast = objApp.ActiveDocument;
if (objDocBeforeLast != null)
{
objDocBeforeLast.Close(
ref objFalse, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RouteDocument
);
}
}
//保存到輸出文件
SaveAs(outDoc);
foreach (Document objDocument in objApp.Documents)
{
objDocument.Close(
ref objFalse, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RouteDocument
);
}
}
finally
{
objApp.Quit(
ref objMissing, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RoutDocument
);
objApp = null;
}
}
///
/// 循環(huán)合并多個文件(復(fù)制合并重復(fù)的文件)
///
/// 模板文件
/// 需要合并的文件
/// 合并后的輸出文件
public void CopyMerge(string tempDoc, string strCopyFolder, string outDoc)
{
string[] arrFiles = Directory.GetFiles(strCopyFolder);
CopyMerge(tempDoc, arrFiles, outDoc);
}
#endregion
#region 循環(huán)合并多個文件(插入合并文件)
///
/// 循環(huán)合并多個文件(插入合并文件)
///
/// 模板文件
/// 需要合并的文件
/// 合并后的輸出文件
public void InsertMerge(string tempDoc, string[] arrCopies, string outDoc)
{
object objMissing = Missing.Value;
object objFalse = false;
object confirmConversion = false;
object link = false;
object attachment = false;
try
{
//打開模板文件
Open(tempDoc);
foreach (string strCopy in arrCopies)
{
objApp.Selection.InsertFile(
strCopy,
ref objMissing,
ref confirmConversion,
ref link,
ref attachment
);
}
//保存到輸出文件
SaveAs(outDoc);
foreach (Document objDocument in objApp.Documents)
{
objDocument.Close(
ref objFalse, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RouteDocument
);
}
}
finally
{
objApp.Quit(
ref objMissing, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RoutDocument
);
objApp = null;
}
}
///
/// 循環(huán)合并多個文件(插入合并文件)
///
/// 模板文件
/// 需要合并的文件
/// 合并后的輸出文件
public void InsertMerge(string tempDoc, string strCopyFolder, string outDoc)
{
string[] arrFiles = Directory.GetFiles(strCopyFolder);
InsertMerge(tempDoc, arrFiles, outDoc);
}
#endregion
}
}2.C# 實(shí)現(xiàn)將多個word文檔合并成一個word文檔的功能
完整代碼
public class WordClass
{
Microsoft.Office.Interop.Word.Application objApp = null;
Document objDocLast = null;
Document objDocBeforeLast = null;
public WordClass()
{
objApp = new Application();
}
#region 打開文件
public void Open(string tempDoc)
{
object objTempDoc = tempDoc;
object objMissing = System.Reflection.Missing.Value;
objDocLast = objApp.Documents.Open(
ref objTempDoc, //FileName
ref objMissing, //ConfirmVersions
ref objMissing, //ReadOnly
ref objMissing, //AddToRecentFiles
ref objMissing, //PasswordDocument
ref objMissing, //PasswordTemplate
ref objMissing, //Revert
ref objMissing, //WritePasswordDocument
ref objMissing, //WritePasswordTemplate
ref objMissing, //Format
ref objMissing, //Enconding
ref objMissing, //Visible
ref objMissing, //OpenAndRepair
ref objMissing, //DocumentDirection
ref objMissing, //NoEncodingDialog
ref objMissing //XMLTransform
);
objDocLast.Activate();
}
#endregion
#region 保存文件到輸出模板
public void SaveAs(string outDoc)
{
object objMissing = System.Reflection.Missing.Value;
object objOutDoc = outDoc;
objDocLast.SaveAs(
ref objOutDoc, //FileName
ref objMissing, //FileFormat
ref objMissing, //LockComments
ref objMissing, //PassWord
ref objMissing, //AddToRecentFiles
ref objMissing, //WritePassword
ref objMissing, //ReadOnlyRecommended
ref objMissing, //EmbedTrueTypeFonts
ref objMissing, //SaveNativePictureFormat
ref objMissing, //SaveFormsData
ref objMissing, //SaveAsAOCELetter,
ref objMissing, //Encoding
ref objMissing, //InsertLineBreaks
ref objMissing, //AllowSubstitutions
ref objMissing, //LineEnding
ref objMissing //AddBiDiMarks
);
}
#endregion
#region 循環(huán)合并多個文件(復(fù)制合并重復(fù)的文件)
/// <summary>
/// 循環(huán)合并多個文件(復(fù)制合并重復(fù)的文件)
/// </summary>
/// <param name="tempDoc">模板文件</param>
/// <param name="arrCopies">需要合并的文件</param>
/// <param name="outDoc">合并后的輸出文件</param>
public void CopyMerge(string tempDoc, string[] arrCopies, string outDoc)
{
object objMissing = Missing.Value;
object objFalse = false;
object objTarget = WdMergeTarget.wdMergeTargetSelected;
object objUseFormatFrom = WdUseFormattingFrom.wdFormattingFromSelected;
try
{
//打開模板文件
Open(tempDoc);
foreach (string strCopy in arrCopies)
{
objDocLast.Merge(
strCopy, //FileName
ref objTarget, //MergeTarget
ref objMissing, //DetectFormatChanges
ref objUseFormatFrom, //UseFormattingFrom
ref objMissing //AddToRecentFiles
);
objDocBeforeLast = objDocLast;
objDocLast = objApp.ActiveDocument;
if (objDocBeforeLast != null)
{
objDocBeforeLast.Close(
ref objFalse, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RouteDocument
);
}
}
//保存到輸出文件
SaveAs(outDoc);
foreach (Document objDocument in objApp.Documents)
{
objDocument.Close(
ref objFalse, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RouteDocument
);
}
}
finally
{
objApp.Quit(
ref objMissing, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RoutDocument
);
objApp = null;
}
}
/// <summary>
/// 循環(huán)合并多個文件(復(fù)制合并重復(fù)的文件)
/// </summary>
/// <param name="tempDoc">模板文件</param>
/// <param name="arrCopies">需要合并的文件</param>
/// <param name="outDoc">合并后的輸出文件</param>
public void CopyMerge(string tempDoc, string strCopyFolder, string outDoc)
{
string[] arrFiles = Directory.GetFiles(strCopyFolder);
CopyMerge(tempDoc, arrFiles, outDoc);
}
#endregion
#region 循環(huán)合并多個文件(插入合并文件)
/// <summary>
/// 循環(huán)合并多個文件(插入合并文件)
/// </summary>
/// <param name="tempDoc">模板文件</param>
/// <param name="arrCopies">需要合并的文件</param>
/// <param name="outDoc">合并后的輸出文件</param>
public void InsertMerge(string tempDoc, List<string> arrCopies, string outDoc)
{
object objMissing = Missing.Value;
object objFalse = false;
object confirmConversion = false;
object link = false;
object attachment = false;
try
{
//打開模板文件
Open(tempDoc);
foreach (string strCopy in arrCopies)
{
objApp.Selection.InsertFile(
strCopy,
ref objMissing,
ref confirmConversion,
ref link,
ref attachment
);
}
//保存到輸出文件
SaveAs(outDoc);
foreach (Document objDocument in objApp.Documents)
{
objDocument.Close(
ref objFalse, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RouteDocument
);
}
}
finally
{
objApp.Quit(
ref objMissing, //SaveChanges
ref objMissing, //OriginalFormat
ref objMissing //RoutDocument
);
objApp = null;
}
}
/// <summary>
/// 循環(huán)合并多個文件(插入合并文件)
/// </summary>
/// <param name="tempDoc">模板文件</param>
/// <param name="arrCopies">需要合并的文件</param>
/// <param name="outDoc">合并后的輸出文件</param>
public void InsertMerge(string tempDoc, string strCopyFolder, string outDoc)
{
string[] arrFiles = Directory.GetFiles(strCopyFolder);
List<string> files = new List<string>();
for (int i = 0; i < arrFiles.Count(); i++)
{
if (arrFiles[i].Contains("doc"))
{
files.Add(arrFiles[i]);
}
}
InsertMerge(tempDoc, files, outDoc);
}
#endregion
#region 合并文件夾下的所有txt文件
/// <summary>
/// 合并多個txt文件
/// </summary>
/// <param name="infileName">文件存在的路勁</param>
/// <param name="outfileName">輸出文件名稱</param>
public void CombineFile(string filePath, string outfileName)
{
string[] infileName = Directory.GetFiles(filePath, "*.txt");
int b;
int n = infileName.Length;
FileStream[] fileIn = new FileStream[n];
using (FileStream fileOut = new FileStream(outfileName, FileMode.Create))
{
for (int i = 0; i < n; i++)
{
try
{
fileIn[i] = new FileStream(infileName[i], FileMode.Open);
while ((b = fileIn[i].ReadByte()) != -1)
fileOut.WriteByte((byte)b);
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
fileIn[i].Close();
}
}
}
}
#endregion
}到此這篇關(guān)于C#調(diào)用OpenXml合并word文檔中的表格單元格的文章就介紹到這了,更多相關(guān)C# OpenXml合并word內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Unity3D利用DoTween實(shí)現(xiàn)卡牌翻轉(zhuǎn)效果
這篇文章主要為大家詳細(xì)介紹了Unity3D利用DoTween實(shí)現(xiàn)卡牌翻轉(zhuǎn)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
C# 如何在WINForm程序中創(chuàng)建XML文件
這篇文章主要介紹了C# 如何在WINForm程序中創(chuàng)建XML文件,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-02-02
C#獲取Windows進(jìn)程監(jiān)聽的TCP/UDP端口實(shí)例
本文介紹了C#獲取Windows下某進(jìn)程監(jiān)聽的TCP/UDP端口的方法,希望對您有所幫助。2013-11-11
C#與js實(shí)現(xiàn)去除textbox文本框里面重復(fù)記錄的方法
這篇文章主要介紹了C#與js實(shí)現(xiàn)去除textbox文本框里面重復(fù)記錄的方法,很實(shí)用的功能,需要的朋友可以參考下2014-08-08
基于C#實(shí)現(xiàn)WinForm開發(fā)操作系統(tǒng)的文件管理系統(tǒng)代碼
基于C#的WinForm應(yīng)用程序來模擬操作系統(tǒng)文件管理系統(tǒng),可以幫助用戶在Windows環(huán)境下進(jìn)行文件的創(chuàng)建、移動、刪除與搜索等操作,這種模擬工具有助于學(xué)習(xí)文件系統(tǒng)的工作原理以及測試和開發(fā)其他軟件項(xiàng)目2024-12-12
C# winfrom 模擬ftp文件管理實(shí)現(xiàn)代碼
從網(wǎng)上找到的非常好用的模擬ftp管理代碼,整理了一下,希望對需要的人有幫助2014-01-01
C#結(jié)合AForge實(shí)現(xiàn)攝像頭錄像
最近由于興趣學(xué)習(xí)了下在C#上使用AForge錄制攝像頭視頻并壓縮編碼??傮w上來說這個第三方.net視覺開發(fā)庫還是比較穩(wěn)定的2017-09-09

