.net core 3.1框架引用NPOI动态导出World文档,包含分页、单元格合并基本功能

.net core 3.1框架引用NPOI动态导出World文档,包含分页、单元格合并基本功能

1.引用第三方库NPOI

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200715165359496.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQzMzM4,size_16,color_FFFFFF,t_70)

动态生成表格实体类

using ExportWorld.Utility;
using Newtonsoft.Json.Linq;
using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;

namespace ExportWorld
{
    public class SaveWorld
    {
        /// <summary>
        /// 外部调用
        /// </summary>
        /// <param name="title"></param>
        /// <param name="subTitle"></param>
        /// <param name="headInfo"></param>
        /// <param name="dt"></param>
        /// <param name="footInfo"></param>
        /// <param name="page">页数(测试用)</param>
        public static void Show(string title, string subTitle, JObject headInfo, DataTable dt, JObject footInfo, int page)
        {

            string workFileName = "入库单8";
            var uploadPath = @"D:\C#Test\ExportWorld\Save";
            string fileName = string.Format("{0}.docx", workFileName, System.Text.Encoding.UTF8);
            if (!Directory.Exists(uploadPath))
            {
                Directory.CreateDirectory(uploadPath);
            }
            using (var stream = new FileStream(Path.Combine(uploadPath, fileName), FileMode.Create, FileAccess.Write))
            {
                //创建document文档对象对象实例
                XWPFDocument document = new XWPFDocument();
                document.Document.body.sectPr = new CT_SectPr();

                CT_SectPr m_SectPr = document.Document.body.sectPr;
                //页面设置A4横向
                m_SectPr.pgSz.w = (ulong)16838;
                m_SectPr.pgSz.h = (ulong)11906;
                #region 创建表格
                FillWorldData(document, title, subTitle, headInfo, dt, footInfo);
                //测试分页
                if (page != 0)
                {

                    XWPFParagraph xWPFParagraph = document.CreateParagraph();
                    xWPFParagraph.CreateRun().AddBreak();//分页
                    FillWorldData(document, title, subTitle, headInfo, dt, footInfo);
                }
                #region 页脚
                CT_Ftr m_ftr = new CT_Ftr();
                m_ftr.Items = new System.Collections.ArrayList();
                CT_SdtBlock m_Sdt = new CT_SdtBlock();
                CT_SdtPr m_SdtPr = m_Sdt.AddNewSdtPr();
                CT_SdtDocPart m_SdtDocPartObj = m_SdtPr.AddNewDocPartObj();
                m_SdtDocPartObj.AddNewDocPartGallery().val = "PageNumbers (Bottom of Page)";
                m_SdtDocPartObj.docPartUnique = new CT_OnOff();
                CT_SdtContentBlock m_SdtContent = m_Sdt.AddNewSdtContent();
                CT_P m_SdtContentP = m_SdtContent.AddNewP();
                CT_PPr m_SdtContentPpPr = m_SdtContentP.AddNewPPr();
                m_SdtContentPpPr.AddNewJc().val = ST_Jc.center;
                m_SdtContentP.Items = new System.Collections.ArrayList();
                CT_SimpleField m_fldSimple = new CT_SimpleField();
                m_fldSimple.instr = " PAGE   \\*MERGEFORMAT ";
                m_SdtContentP.Items.Add(m_fldSimple);
                m_ftr.Items.Add(m_Sdt);
                XWPFRelation Frelation = XWPFRelation.FOOTER;
                XWPFFooter m_f = (XWPFFooter)document.CreateRelationship(Frelation, XWPFFactory.GetInstance(), document.FooterList.Count + 1);
                m_f.SetHeaderFooter(m_ftr);
                CT_HdrFtrRef m_HdrFtr = m_SectPr.AddNewFooterReference();
                m_HdrFtr.type = ST_HdrFtr.@default;
                m_HdrFtr.id = m_f.GetPackageRelationship().Id;
                #endregion
                document.Write(stream);
                #endregion
            }
        }
        /// <summary>
        /// 合并区域(有问题)
        /// </summary>
        /// <param name="table"></param>
        /// <param name="fromCol"></param>
        /// <param name="toCol"></param>
        /// <param name="fromRow"></param>
        /// <param name="toRow"></param>
        private static void MyMergeCells(XWPFTable table, int fromCol,int toCol, int fromRow, int toRow)
        {
            for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++)
            {
                if (fromCol < toCol)
                {
                    table.GetRow(rowIndex).MergeCells(fromCol, toCol);//合并列
                }
                XWPFTableCell cell = table.GetRow(rowIndex).GetCell(fromCol);
                CT_Tc cttc = cell.GetCTTc();
                
                if (cttc.tcPr == null)
                {
                    cttc.AddNewTcPr();
                }
                //第一个合并单元格用重启合并值设置
                if (rowIndex == fromRow)
                {
                    cell.GetCTTc().AddNewTcPr().AddNewVMerge().val = ST_Merge.restart;
                }
                else
                {
                    //合并第一个单元格的单元被设置为“继续”
                    cell.GetCTTc().AddNewTcPr().AddNewVMerge().val = ST_Merge.@continue;
                }
            }

        }
        /// <summary>
        /// 动态生成表格填充数据
        /// </summary>
        /// <param name="document"></param>
        /// <param name="title">标题</param>
        /// <param name="subTitle">副标题</param>
        /// <param name="headInfo">表格头部信息</param>
        /// <param name="dt">表格中间数据集</param>
        /// <param name="footInfo">表格底部信息</param>
        /// <param name="fontColor">字体颜色</param>
        /// <returns></returns>
        public static string FillWorldData(XWPFDocument document, string title, string subTitle, JObject headInfo, DataTable dt, JObject footInfo, string fontColor = "000000")
        {
            try
            {
                int rows = 0, cols = 0, index = 0, temp = 0, startRow = 0, count=1;
                if (!string.IsNullOrWhiteSpace(title))
                    rows += 1;
                if (!string.IsNullOrWhiteSpace(subTitle))
                    rows += 1;
                if (headInfo != null && headInfo.Count > 0)
                {
                    count += ((headInfo.Count) % 2 == 1 ? headInfo.Count / 2 : headInfo.Count / 2 - 1);
                    rows += count;
                }

                if (footInfo != null && footInfo.Count > 0)
                {
                    count = 1;
                    count += ((footInfo.Count) % 2 == 1 ? footInfo.Count / 2 : footInfo.Count / 2 - 1);
                    rows += count;
                }
                   
                if (dt != null && dt.Rows.Count > 0)
                {
                    rows += dt.Rows.Count;
                    cols += dt.Columns.Count;
                }
                XWPFTable firstXwpfTable = document.CreateTable(rows, cols);//创建表格
                firstXwpfTable.Width = 5500;//总宽度
                if (!string.IsNullOrWhiteSpace(title.Trim()))
                {
                    firstXwpfTable.GetRow(startRow).MergeCells(0, cols - 1);//合并列
                    firstXwpfTable.GetRow(startRow).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, title, ParagraphAlignment.CENTER, 24, true, 22, fontColor));//标题
                    startRow++;
                }
                if (!string.IsNullOrWhiteSpace(subTitle.Trim()))
                {
                    firstXwpfTable.GetRow(startRow).MergeCells(0, cols - 1);//合并列
                    firstXwpfTable.GetRow(startRow).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, subTitle, ParagraphAlignment.CENTER, 24, true, 16, fontColor));//附标题
                    startRow++;
                }
                if (headInfo != null && headInfo.Count > 0)//头部
                {
                    foreach (var item in headInfo)
                    {
                        temp = startRow;
                        if (index % 2 == 0)
                        {
                            firstXwpfTable.GetRow(startRow).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, item.Key, ParagraphAlignment.CENTER, 24, true, 10, fontColor));
                            firstXwpfTable.GetRow(startRow).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, item.Value.ToString(), ParagraphAlignment.CENTER, 24, false, 10, fontColor));
                        }
                        else
                        {
                            firstXwpfTable.GetRow(startRow).GetCell(cols - 2).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, item.Key, ParagraphAlignment.CENTER, 24, true));
                            firstXwpfTable.GetRow(startRow).GetCell(cols - 1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, item.Value.ToString(), ParagraphAlignment.CENTER, 24, false, 10, fontColor));
                            if (!index.Equals(headInfo.Count - 1))
                            {
                                startRow++;
                            }
                        }
                        index++;
                    }
                    //MyMergeCells(firstXwpfTable, 2, cols-3,startRow-1, temp + ((index % 2) == 1 ? index / 2 : index / 2 - 1)-1);//合并区域
                    startRow++;
                }
                if (dt != null && dt.Rows.Count > 0)//中间数据
                {
                    if (headInfo != null && headInfo.Count > 0)
                    {
                        //合并单元格
                        firstXwpfTable.GetRow(startRow).MergeCells(0, cols - 1);//合并
                        startRow++;
                    }
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        firstXwpfTable.GetRow(startRow).GetCell(j).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, dt.Columns[j].ToString(), ParagraphAlignment.CENTER, 24, true, 10, fontColor));//列名加粗
                    }
                    startRow++;
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        for (int j = 0; j < dt.Columns.Count; j++)
                        {
                            firstXwpfTable.GetRow(startRow).GetCell(j).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, dt.Rows[i][j].ToString(), ParagraphAlignment.CENTER, 24, false, 10, fontColor));
                        }

                        if (i == dt.Rows.Count - 1)
                        {
                            firstXwpfTable.GetRow(startRow).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, dt.Rows[i][0].ToString(), ParagraphAlignment.CENTER, 24, true, 10, fontColor));//最后一行列名加粗
                        }
                        startRow++;
                    }
                }
                if (footInfo != null && footInfo.Count > 0)//尾部
                {
                    if (dt != null && dt.Rows.Count > 0)
                    {
                        firstXwpfTable.GetRow(startRow).MergeCells(0, cols - 1);//合并
                        firstXwpfTable.GetRow(startRow).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, "", ParagraphAlignment.LEFT, 10, false, 10, fontColor));
                        startRow++;
                    }
                    index = 0;
                    foreach (var item in footInfo)
                    {
                        temp = startRow;
                        if (index % 2 == 0)
                        {
                            firstXwpfTable.GetRow(startRow).GetCell(0).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, item.Key, ParagraphAlignment.CENTER, 24, true));
                            firstXwpfTable.GetRow(startRow).GetCell(1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, item.Value.ToString(), ParagraphAlignment.CENTER, 24, false, 10, fontColor));

                        }
                        else
                        {
                            firstXwpfTable.GetRow(startRow).GetCell(cols - 2).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, item.Key, ParagraphAlignment.CENTER, 24, true));
                            firstXwpfTable.GetRow(startRow).GetCell(cols - 1).SetParagraph(NpoiWordParagraphTextStyleHelper._.SetTableParagraphInstanceSetting(document, firstXwpfTable, item.Value.ToString(), ParagraphAlignment.CENTER, 24, false, 10, fontColor));
                            if (!index.Equals(footInfo.Count - 1))
                            {
                                startRow++;
                            }
                        }
                        index++;
                    }
                    //MyMergeCells(firstXwpfTable, 2, 1,startRow, temp + ((index % 2) == 1 ? index / 2 : index / 2 - 1));//合并区域
                }
            }
            catch (Exception ex)
            {

                return ex.Message;
            }

            return "";
        }

    }
}

生成wrold文本样式

using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.Text;

namespace ExportWorld.Utility
{
    public class NpoiWordParagraphTextStyleHelper
    {
        private static NpoiWordParagraphTextStyleHelper _exportHelper;

        public static NpoiWordParagraphTextStyleHelper _
        {
            get => _exportHelper ?? (_exportHelper = new NpoiWordParagraphTextStyleHelper());
            set => _exportHelper = value;
        }
       
        /// <summary>
        /// 创建word文档中的段落对象和设置段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
        /// </summary>
        /// <param name="document">document文档对象</param>
        /// <param name="fillContent">段落第一个文本对象填充的内容</param>
        /// <param name="isBold">是否加粗</param>
        /// <param name="fontSize">字体大小</param>
        /// <param name="fontFamily">字体</param>
        /// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
        /// <param name="isStatement">是否在同一段落创建第二个文本对象(解决同一段落里面需要填充两个或者多个文本值的情况,多个文本需要自己拓展,现在最多支持两个)</param>
        /// <param name="secondFillContent">第二次声明的文本对象填充的内容,样式与第一次的一致</param>
        /// <param name="fontColor">字体颜色--十六进制</param>
        /// <param name="isItalic">是否设置斜体(字体倾斜)</param>
        /// <returns></returns>
        public XWPFParagraph ParagraphInstanceSetting(XWPFDocument document, string fillContent, bool isBold, int fontSize, string fontFamily, ParagraphAlignment paragraphAlign, bool isStatement = false, string secondFillContent = "", string fontColor = "000000", bool isItalic = false)
        {
            XWPFParagraph paragraph = document.CreateParagraph();//创建段落对象
            paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)


            XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
            xwpfRun.IsBold = isBold;//文字加粗
            xwpfRun.SetText(fillContent);//填充内容
            xwpfRun.FontSize = fontSize;//设置文字大小
            xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
            xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
            xwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定

            if (!isStatement) return paragraph;

            XWPFRun secondXwpfRun = paragraph.CreateRun();//创建段落文本对象
            secondXwpfRun.IsBold = isBold;//文字加粗
            secondXwpfRun.SetText(secondFillContent);//填充内容
            secondXwpfRun.FontSize = fontSize;//设置文字大小
            secondXwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
            secondXwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
            secondXwpfRun.SetFontFamily(fontFamily, FontCharRange.None); //设置标题样式如:(微软雅黑,隶书,楷体)根据自己的需求而定
            return paragraph;
        }

        /// <summary>  
        /// 创建Word文档中表格段落实例和设置表格段落文本的基本样式(字体大小,字体,字体颜色,字体对齐位置)
        /// </summary>  
        /// <param name="document">document文档对象</param>  
        /// <param name="table">表格对象</param>  
        /// <param name="fillContent">要填充的文字</param>  
        /// <param name="paragraphAlign">段落排列(左对齐,居中,右对齐)</param>
        /// <param name="textPosition">设置文本位置(设置两行之间的行间,从而实现表格文字垂直居中的效果),从而实现table的高度设置效果  </param>
        /// <param name="isBold">是否加粗(true加粗,false不加粗)</param>
        /// <param name="fontSize">字体大小</param>
        /// <param name="fontColor">字体颜色--十六进制</param>
        /// <param name="isItalic">是否设置斜体(字体倾斜)</param>
        /// <returns></returns>  
        public XWPFParagraph SetTableParagraphInstanceSetting(XWPFDocument document, XWPFTable table, string fillContent, ParagraphAlignment paragraphAlign, int textPosition = 24, bool isBold = false, int fontSize = 10, string fontColor = "000000", bool isItalic = false)
        {
            var para = new CT_P();
            //设置单元格文本对齐
            para.AddNewPPr().AddNewTextAlignment();

            XWPFParagraph paragraph = new XWPFParagraph(para, table.Body);//创建表格中的段落对象
            paragraph.Alignment = paragraphAlign;//文字显示位置,段落排列(左对齐,居中,右对齐)
            //paragraph.FontAlignment =Convert.ToInt32(ParagraphAlignment.CENTER);//字体在单元格内显示位置与 paragraph.Alignment效果相似

            XWPFRun xwpfRun = paragraph.CreateRun();//创建段落文本对象
            xwpfRun.SetText(fillContent);
            xwpfRun.FontSize = fontSize;//字体大小
            xwpfRun.SetColor(fontColor);//设置字体颜色--十六进制
            xwpfRun.IsItalic = isItalic;//是否设置斜体(字体倾斜)
            xwpfRun.IsBold = isBold;//是否加粗
            xwpfRun.SetFontFamily("宋体", FontCharRange.None);//设置字体(如:微软雅黑,华文楷体,宋体)
            return paragraph;
        }
    }
}

测试调用

 static void Main(string[] args)
        {
			try
			{
                DataTable dt = new DataTable();
                dt.Columns.Add(new DataColumn("Name", Type.GetType("System.String")));
                dt.Columns.Add(new DataColumn("Age", Type.GetType("System.Int32")));
                dt.Columns.Add(new DataColumn("Score", Type.GetType("System.Decimal")));
                dt.Columns.Add(new DataColumn("CreateTime", Type.GetType("System.DateTime")));
                dt.Columns.Add(new DataColumn("cloum1", Type.GetType("System.Int32")));
                dt.Columns.Add(new DataColumn("cloum2", Type.GetType("System.Int32")));
                dt.Columns.Add(new DataColumn("cloum3", Type.GetType("System.Int32")));

                DataRow dr = dt.NewRow();
                dr["Name"] = "张三";
                dr["Age"] = 28;
                dr["Score"] = 85.5;
                dr["CreateTime"] = DateTime.Now;
                dr["cloum1"] = 1;
                dr["cloum2"] =2;
                dr["cloum3"] = 3;
                dt.Rows.Add(dr);

                dr = dt.NewRow();
                dr["Name"] = "李四";
                dr["Age"] = 24;
                dr["Score"] = 72;
                dr["CreateTime"] = DateTime.Now;
                dr["cloum1"] = 1;
                dr["cloum2"] = 2;
                dr["cloum3"] = 3;
                dt.Rows.Add(dr);

                dr = dt.NewRow();
                dr["Name"] = "王五";
                dr["Age"] = 36;
                dr["Score"] = 63.5;
                dr["CreateTime"] = DateTime.Now;
                dr["cloum1"] = 1;
                dr["cloum2"] = 2;
                dr["cloum3"] = 3;
                dt.Rows.Add(dr);

                dr = dt.NewRow();
                dr["Name"] = "合计";
                dr["Age"] = 100;
                dr["Score"] = 100;
                dt.Rows.Add(dr);
                string checkTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                JObject head = new JObject();
                head["入库单号"] = "DPT-20200707-0000012";
                head["创建日期"] = checkTime;
                head["操作员"] = "哈哈";

                JObject foot = new JObject();
                foot["入库用户"] = "喜喜";
                foot["签名"] = "";
                SaveWorld.Show("入库单","",head,dt,foot,2);
			}
			catch (Exception ex)
			{

				throw ex;
			}
        }

生成效果

在这里插入图片描述

参考文章

https://www.cnblogs.com/Can-daydayup/p/11588531.html @追逐时光者
等其它一些优秀文章,不好之处请见谅,错误之处请大佬们指出。
word合并区域还存在问题,希望有人能帮忙指导一下
亲测可用!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值