开发者

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 };                  
                }
            }
        }
    }
}

结果如下 

C#调用OpenXml合并word文档中的表格单元格

方法补充:

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)!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜