原文地址:https://www.cnblogs.com/qs315/p/13533765.html
使用Docx.Core创建word表格
下载DocxCore Nuget包 当前版本 1.0.7
Install-Package DocxCore -Version 1.0.7
创建表格参数
TableDto.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /// <summary> /// 表格 /// </summary> public class TableDto { /// <summary> /// 表头 /// </summary> public List<List<TableTdDto>> TRS { get ; set ; } /// <summary> /// 表内容 /// </summary> public List<List<TableTdDto>> TDS { get ; set ; } } |
TableTdDto.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /// <summary> /// 表格TD属性 /// </summary> public class TableTdDto { /// <summary> /// 宽度比例 /// </summary> public int W { get ; set ; } /// <summary> /// 内容 /// </summary> public string N { get ; set ; } /// <summary> /// 占列数,对应 colspan /// </summary> public int CL { get ; set ; } = 1; /// <summary> /// 占行数,对应 rowspan /// </summary> public int RL { get ; set ; } = 1; /// <summary> /// 个数,扩展 /// </summary> public int C1 { get ; set ; } = 0; /// <summary> /// 样式 /// </summary> public string S { get ; set ; } } |
使用Docx创建表格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | public class DocxHelper { /// <summary> /// 创建word /// </summary> /// <param name="dto"></param> public static void CreateWord(TableDocumentDto dto) { var uploadPath = AppDomain.CurrentDomain.BaseDirectory; string fileName = string .Format( "{0}.docx" , dto.Title, System.Text.Encoding.UTF8); // Create a document. using ( var document = DocX.Create(uploadPath+fileName)) { var first = dto.Table.TRS.FirstOrDefault(); var cols = first.Sum(o => o.CL); var rows = dto.Table.TRS.Count + dto.Table.TDS.Count; var headerTable = dto.Table.TRS; var w = first.Sum(o => o.W); var allWidth = w == 0 ? 5200 : w; Table table1 = document.AddTable(rows, cols); table1.Design = TableDesign.TableGrid; //表格样式 table1.Alignment = Alignment.center; //设置表格居中 headerTable.AddRange(dto.Table.TDS); for ( int i = 0; i < headerTable.Count; i++) { if (table1.Rows.Count < headerTable.Count) { throw new Exception( "请检查表格参数" ); } var rol = headerTable[i].Max(o => o.RL); int a = 0; //表示起始列位置 for ( int j = 0; j < headerTable[i].Count; j++) { if (table1.Rows[i].Cells.Count < headerTable[i].Count) { throw new Exception( "请检查表格参数" ); } if (headerTable[i][j].CL > 1 && headerTable[i][j].RL > 1) { throw new Exception( "当前无法同时合并行和列" ); } var width = headerTable[i][j].W == 0 ? 120 : headerTable[i][j].W; //当前合并列 if (headerTable[i][j].CL > 1) { //当前需要合并列 //MergeCells(起始列,结束列); table1.Rows[i].MergeCells(a, (headerTable[i][j].CL - 1) + a); //合并列 table1.Rows[i].Cells[a].Paragraphs[0].Append(headerTable[i][j].N).Bold(); a += headerTable[i][j].CL - 1; } else if (headerTable[i][j].RL > 1) { //当前需要合并行 //MergeCellsInColumn(起始列,起始行,结束行) table1.MergeCellsInColumn(j, i, (i+headerTable[i][j].RL) - 1); //合并行 table1.Rows[i].Cells[a].Paragraphs[0].Append(headerTable[i][j].N).Bold(); a++; } else { table1.Rows[i].Cells[a].Paragraphs[0].Append(headerTable[i][j].N).Bold(); a++; } } } //table1.MergeCellsInColumn(2, 2, 3); //table1.Rows[0].Cells[0].Paragraphs[0].Append("列1").Bold(); //table1.Rows[0].Cells[1].Paragraphs[0].Append("列2").Bold(); //table1.Rows[0].Cells[0].Width = 100; //设置单元格宽度 //table1.Rows[0].Cells[1].Width = 100; //table1.Rows[1].MergeCells(1, 2); //table1.Rows[1].Cells[1].Paragraphs[0].Append("列2").Bold(); Paragraph p = document.InsertParagraph(); p.Alignment = Alignment.center; p.Append(dto.Title).Bold(); p.InsertTableAfterSelf(table1); document.Save(); Console.WriteLine($ "表【{dto.Title}.docx】创建成功" ); } } } |
在使用时 行和列一起合并的时候出现索引无法找到问题 所以现在无法进行行列一起合并 只能单独合并
一定要正确定义TableDto 使用CL和RL可进行合并,但不能同时使用 每一列都是固定的 例如
list
集合里有7条数据 其中有一条数据进行了合并占用了两格
所以有8列数据 那么以下所有的数据都最多只能占用8列,超出将会报错
如果要上传图片的话 使用以下方法 将图片放置在单元格中
1 2 3 4 5 6 7 | var image = document.AddImage( @"D:/其他文件/图片/" + @"logo.png" ); // Create a picture from image. var picture = image.CreatePicture(25, 100); table1.Rows[i].Cells[a].Paragraphs[0].AppendPicture(picture); //第一张图 table1.Rows[i].Cells[a].Paragraphs[0].AppendPicture(picture); //第二张图 table1.Rows[i].Cells[a].Paragraphs[0].AppendPicture(picture); //第三张图 //当前图片都放置在同一单元格中 |
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | class Program { static void Main( string [] args) { var filePath = @"D:\文档\标题2.docx" ; var list = new List<List<TableTdDto>>(); list.Add( new List<TableTdDto>() { new TableTdDto(){ N = "序号" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = "检查项目" , CL = 2, RL = 1, W = 10, }, new TableTdDto(){ N = "扣分标准" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = "应得分数" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = "扣减分数" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = "实得分数" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = "备注" , CL = 1, RL = 1, W = 10, }, }); var tes = new List<List<TableTdDto>>(); tes.Add( new List<TableTdDto>() { new TableTdDto(){ N = "这是序号" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = "保证项目" , CL = 1, RL = 6, W = 10, }, new TableTdDto(){ N = "安全生产责任制" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = @"测试数据" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = @"10" , CL = 1, RL = 1, W = 10, } }); var tableTd = new List<TableTdDto>(); for ( int i = 0; i < 5; i++) { tableTd.Add( new TableTdDto() { N = "测试数据" , CL = 1, RL = 1, W = 10, }); tes.Add(tableTd); } tes.Add( new List<TableTdDto>() { new TableTdDto(){ N = "1" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = "一般项目" , CL = 1, RL = 5, W = 10, }, new TableTdDto(){ N = "安全生产责任制" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = @"测试数据" , CL = 1, RL = 1, W = 10, }, new TableTdDto(){ N = @"10" , CL = 1, RL = 1, W = 10, } }); var tableTds = new List<TableTdDto>(); for ( int i = 0; i < 4; i++) { tableTds.Add( new TableTdDto() { N = "测试数据" , CL = 1, RL = 1, W = 10, }); tes.Add(tableTd); } var data = new TableDocumentDto() { Title = "安全管理检查评分表" , Table = new TableDto() { TDS = tes, TRS = list } }; DocxHelper.CreateWord(data); Console.ReadKey(); } } |
END
文档太少,例子太少,只有一步一步的试每个方法.最开始用的NPOI
但是NPOI文档都找不到了,合并列还行,到合并行的时候就没办法了,按照其他博客进行操作,太复杂,也没有解释属性和方法的意思,造成即使写了出现错误也不知道为什么会出现这个问题.
Docx虽然文档也没有找到 但是靠猜方法找到了合并行和列的方法 解决了我的问题
例子:https://github.com/xceedsoftware/DocX/tree/master/Xceed.Words.NET.Examples/Samples
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理