C#调用OpenXml合并word文档中的表格单元格
OpenXML合并word文档的表格单元格主要依靠单元格TabelCell的TableCellProperties的HorizontalMerge和 VerticalMerge这两个关键属性,HorizontalMerge用于水平方向的单元格合并,VerticalMerge用于垂直方向的单元格合并,它们都使用MergedCellValues枚举值,其中MergedCellValues.Restart表示开始合并,MergedCellValues.Continue表示被合并。
合并单元格主要由标记为Restart的起始单元格和一个或多个标记为Continue的后续单元格组成,起始单元格是合并区域的第一个单元格,该单元格的TableCellProperties的HorizontalMerge或VerticalMerge属性值为Restart,起始单元格之后的所有单元格都使用Continue 值,表明它们属于前一个起始单元格
以省份景点统计为例,将同一省份的景点数据相邻显示,超过一行则将省份名称单元格合并,然后紧接一行计算同一省份的景点票价合计费用,主要代码、统计表格模板及统计表格数据如下所示:
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), "票价合计");
FillTabelCellData(cells.ElementAt(3), sum.ToString());
MergeCellsHorizontally(curRow, 0, 2);
lineIndex++;
}
/// <summary>
/// 水平合并同一行内的连续单元格
/// </summary>
/// <param name="row">目标行</param>
/// <param name="startColumnIndex">起始列索引</param>
/// <param name="endColumnIndex">结束列索引</param>
private static void MergeCellsHorizontally(TableRow row, int startColumnIndex, int endColumnIndex)
{
// 获取该行所有单元格
var cells = row.Elements<TableCell>().ToList();
// 确保起始索引有效,并且起始索引小于结束索引
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">结束行索引</param>
private static void MergeCellsVertically(List<TableRow> rows, int columnIndex, int startRowIndex, int endRowIndex)
{
// 确保行索引有效
if (startRowIndex < rows.Count && endRowIndex < rows.Count && startRowIndex <= endRowIndex)
{
// 获取起始行的目标单元格
var startRowCells = rows[startRowIndex].Elements<TableCell>().ToList();
// 获取结束行的目标单元格
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 };
GJMXjGfMh// 在被合并的后续单元格设置 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();
// 设置 VerticalMerge 属性,值为Continue 表示这是垂直合并的一部分
mergeCellProps.VerticalMerge = new VerticalMerge { Val = MergedCellValues.Continue };
}
}
}
}
}
结果如下

方法补充:
1.C#合并多个WORD文档
文中提供了两种合并:一是复制合并;一是插入合并,即将多个文档按照先后顺序合并到另一个文档中。
调用方法:
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;//关闭Word的拼写检查
objDocLast.ShowSpellingErrors = false;//关闭Word的拼写错误提示
}
#endregion
#region 保存文件到输出模板
prihttp://www.devze.comvate 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 循环合并多个文件(复制合并重复的文件)
///
/// 循环合并多个文件(复制合并重复的文件)
///
/// 模板文件
/// 需要合并的文件
/// 合并后的输出文件
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;
}
}
///
/// 循环合并多个文件(复制合并重复的文件)
///
/// 模板文件
/// 需要合并的文件
/// 合并后的输出文件
public void CopyMerge(string tempDoc, string strCopyFolder, string outDoc)
{
string[] arrFiles = Directory.GetFiles(strCopyFolder);
CopyMerge(tempDoc, arrFiles, outDoc);
}
#endregion
#region 循环合并多个文件(插入合并文件)
///
/// 循环合并多个文件(插入合并文件)
///
/// 模板文件
/// 需要合并的文件
/// 合并后的输出文件
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;
}
}
///
/// 循环合并多个文件(插入合并文件)
///
/// 模板文件
/// 需要合并的文件
/// 合并后的输出文件
public void InsertMerge(string tempDoc, string strCopyFolder, string outDoc)
{
string[] arrFiles = Directory.GetFiles(strCopyFolder);
InsertMerge(tempDoc, arrFiles, outDoc);
}
#endregion
}
}
2.C# 实现将多个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 循环合并多个文件(复制合并重复的文件)
/// <summary>
/// 循环合并多个文件(复制合并重复的文件)
/// </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>
/// 循环合并多个文件(复制合并重复的文件)
/// </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 循环合并多个文件(插入合并文件)
/// <summary>
/// 循环合并多个文件(插入合并文件)
/// </summary>
/// <param name="tempDoc">模板文js件</param>
/// <param name="arrCopies">需要合并的文件</param>
/// <param name="outDoc">合并后的输出文件</param>
public void InsertMerge(string tempDoc, List<string> arrCopies, string outDoc)
{
ob编程客栈ject 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
python ref objMissing //RoutDocument
);
objApp = null;
}
}
/// <summary>
/// 循环合并多个文件(插入合并文件)
/// </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
}
到此这篇关于C#调用OpenXml合并word文档中的表格单元格的文章就介绍到这了,更多相关C# OpenXml合并word内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
加载中,请稍侯......
精彩评论