当前位置: 首页 > news >正文

C#测试调用OpenXml填充word文档的表格

  使用OpenXml将统计数据输出到word文档的表格中,如果需要生成多页数据的话,需要使用前面文章用到的表格复制功能(参考文献3),同时要计算总页数、当前页数、每页数据等信息并田中到每页的表格内。
以景点统计数据为例,基于DeepSeek生成景点类及22条测试数据,将数据集合中的部分属性输出到word文件的表格中。景点类及word表格模板如下所示:

public class ScenicSpot
{public int Id { get; set; }                     // 景点IDpublic string Name { get; set; }               // 景点名称public string Description { get; set; }        // 景点描述public string Location { get; set; }           // 地理位置public decimal TicketPrice { get; set; }       // 门票价格public double Area { get; set; }               // 占地面积(公顷)public int VisitorCapacity { get; set; }       // 游客容量public DateTime OpenDate { get; set; }         // 开放日期public bool IsWorldHeritage { get; set; }      // 是否世界遗产public double Rating { get; set; }             // 评分(1-5分)public string Category { get; set; }           // 景点类别public int AnnualVisitors { get; set; }        // 年游客量(万人次)
}

在这里插入图片描述
  程序的主要思路是找到word文档中的表格并复制一份到内存,然后计算总页数,接着逐页计算并填充统计数据、页码信息。程序的主要实现逻辑及文档输出效果如下所示。

private static void ProcessDocument(WordprocessingDocument doc, Dictionary<string, string> replacements)
{MainDocumentPart mainPart = doc.MainDocumentPart;if (mainPart == null) return;Body body = mainPart.Document.Body;  string tableTitle = "datatable";// 通过表格属性中的标题查找表格Table targetTable = FindTableByTableTitle(body, tableTitle);if (targetTable == null){Console.WriteLine($"未找到标题为 '{tableTitle}' 的表格");return;}int startRowIndex = 2;//每页填充起始行int endRowIndex = 16;//每页填充结束行int pageInfoRowIndex = 17;//当前页、总页数信息所在行int curPageColIndex = 3;//当前页信息所在列int totalPageColIndex = 4;//总页数信息所在列int linePerPage = 15;//每页填充行数//计算总页数int totalPage = (m_lstScenicSpot.Count % linePerPage == 0) ? (m_lstScenicSpot.Count / linePerPage) : (m_lstScenicSpot.Count / linePerPage + 1);int curPage = 1;int lineIndex = 1;// 克隆表格Table clonedTable = (Table)targetTable.CloneNode(true);Table curTable = targetTable;do{// 如果不是首页,则克隆新表格并插入word文档中if(curPage!=1){                    InsertPageBreakAfterElement(body, curTable);// 在当前表格后插入分页符curTable =(Table)clonedTable.CloneNode(true);//复制新表格InsertElementAfterLastPageBreak(body, curTable);// 在分页符后插入新表格}//取当前页的数据IEnumerable<ScenicSpot> pageData = m_lstScenicSpot.Skip((curPage - 1) * linePerPage).Take(linePerPage);//逐行插入数据var rows = curTable.Elements<TableRow>();if (rows != null && rows.Count() > 0){for (int rowIndex = startRowIndex; (rowIndex <= endRowIndex) && (rowIndex < (startRowIndex + pageData.Count())); rowIndex++){TableRow row = rows.ElementAt(rowIndex);var cells = row.Elements<TableCell>();ScenicSpot rowData = pageData.ElementAt(rowIndex - startRowIndex);FillTabelCellData(cells.ElementAt(0), lineIndex.ToString());FillTabelCellData(cells.ElementAt(1), rowData.Name);FillTabelCellData(cells.ElementAt(2), rowData.Location);FillTabelCellData(cells.ElementAt(3), rowData.Category);FillTabelCellData(cells.ElementAt(4), rowData.Description);lineIndex++;}}// 插入页码FillTargetTableCellContent(curTable, pageInfoRowIndex, curPageColIndex, $"第 {curPage.ToString()} 页");FillTargetTableCellContent(curTable, pageInfoRowIndex, totalPageColIndex, $"共 {totalPage.ToString()} 页");curPage++;}while(curPage <= totalPage);// 保存文档mainPart.Document.Save();
}private static void FillTabelCellData(TableCell cell,string content)
{cell.RemoveAllChildren<Paragraph>();// 添加新的段落和文本内容到单元格中Paragraph para = new Paragraph(new Run(new Text(content)));cell.AppendChild(para);
}private static void FillTargetTableCellContent(Table table, int rowIndex, int columnIndex, string content)
{TableRow row = table.Elements<TableRow>().ElementAt(rowIndex);// 获取目标单元格TableCell cell = row.Elements<TableCell>().ElementAt(columnIndex);// 清除原有内容cell.RemoveAllChildren<Paragraph>();// 创建新段落和文本Paragraph para = new Paragraph();Run run = new Run();run.Append(new Text(content));para.Append(run);cell.Append(para);
}

在这里插入图片描述

参考文献
[1]https://github.com/dotnet/Open-XML-SDK
[2]https://learn.microsoft.com/zh-cn/office/open-xml/open-xml-sdk
[3]https://blog.csdn.net/gc_2299/article/details/151157804

http://www.dtcms.com/a/528634.html

相关文章:

  • 基于python的网站开发项目做外汇网站代理商
  • 对TCP/IP协议的理解
  • 如何判断“IP+端口“通不通
  • tensorrt c++部署
  • TypeScript 基础类型与接口详解
  • MySQL————mysql connect
  • 能打开各种网站的搜索引擎原神网页设计作业
  • 【SpringCloud】Ribbon(LoadBalancer ) 和 Feign
  • Dockerfile 中 ENTRYPOINT 和 CMD 有什么区别 ?
  • 网站数据库模版深圳网站建设黄浦网络 骗钱
  • vs code 下docker使用方法,以php 项目为示例
  • 番禺网站建设哪里好深圳十大传媒公司
  • 前端常见的设计模式
  • 亚马逊云渠道商:如何通过配置自动替换构建故障自愈的云架构?
  • 豆包 Python 和 Java 的 AI 集成及模型转换
  • 深入解析C++命令模式:设计原理与实际应用
  • 商城网站建设目标上海前十名文化传媒公司
  • ExpressionVisitor 的使用场景及方法
  • 《3D端游开放世界动态天气系统与场景交互优化实践日志》
  • Date类自主实现后的反思
  • 网络渗流:爆炸渗流
  • 购物网站建设款流程国外优秀设计网站大全
  • 【C++】STL容器-stack和queue的使用与模拟实现
  • numpy学习笔记(持续更新)
  • linux schedule函数学习
  • 教育培训网站有哪些辽宁网站建设企业定制公司
  • Python机器学习---6.集成学习与随机森林
  • 厦门网站建设公司新能源汽车价格表图片及价格表
  • 二分查找栈堆动态规划
  • 【脚本】提取phpstudy网站对应的PHP版本