NPOI 实现Excel模板导出

 记录一下使用NPOI实现定制的Excel导出模板,已下实现需求及主要逻辑

所需Json数据 对应参数 List<PurQuoteExportDataCrInput> listData

[{"ItemName": "电缆VV3*16+2*10","Spec": "电缆VV3*16+2*10","Uom": "米","Quantity": 10.0,"MinPrice": 100.0,"UseOrg": null,"SumPrice": 3000.0,"Desc": "\r\n备注: \r\n1、只有*拟签数量,*拟签含税单价(元)可修改: \r\n2、底色标记的价格为该物料行的最低报价: \r\n3、若不中标,将拟签数量及价格空着即可: \r\n4、平台拟签数量最多保留4位小数点、拟签含税单价最多保留4位小数点,可能会造成平台总价计算结果与EXCEL计算略有差异,请以平台页面为准\"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n","CardList": [{"Name": "供应商1","Price": 100.0,"SumPrice": 1000.0},{"Name": "供应商2","Price": 200.0,"SumPrice": 2000.0}]},{"ItemName": "电缆VV3*70+1*35","Spec": "电缆VV3*70+1*35","Uom": "米","Quantity": 10.0,"MinPrice": 100.0,"UseOrg": null,"SumPrice": 3000.0,"Desc": "\r\n备注: \r\n1、只有*拟签数量,*拟签含税单价(元)可修改: \r\n2、底色标记的价格为该物料行的最低报价: \r\n3、若不中标,将拟签数量及价格空着即可: \r\n4、平台拟签数量最多保留4位小数点、拟签含税单价最多保留4位小数点,可能会造成平台总价计算结果与EXCEL计算略有差异,请以平台页面为准\"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n","CardList": [{"Name": "供应商1","Price": 100.0,"SumPrice": 1000.0},{"Name": "供应商2","Price": 200.0,"SumPrice": 2000.0}]},{"ItemName": "电缆VV3*95+1*50","Spec": "电缆VV3*95+1*50","Uom": "米","Quantity": 10.0,"MinPrice": 100.0,"UseOrg": null,"SumPrice": 3000.0,"Desc": "\r\n备注: \r\n1、只有*拟签数量,*拟签含税单价(元)可修改: \r\n2、底色标记的价格为该物料行的最低报价: \r\n3、若不中标,将拟签数量及价格空着即可: \r\n4、平台拟签数量最多保留4位小数点、拟签含税单价最多保留4位小数点,可能会造成平台总价计算结果与EXCEL计算略有差异,请以平台页面为准\"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n","CardList": [{"Name": "ZH001","Price": 100.0,"SumPrice": 1000.0},{"Name": "ZH002","Price": 200.0,"SumPrice": 2000.0}]},{"ItemName": "电缆VV3*120+1*70","Spec": "电缆VV3*120+1*70","Uom": "米","Quantity": 10.0,"MinPrice": 0.0,"UseOrg": null,"SumPrice": 0.0,"Desc": "\r\n备注: \r\n1、只有*拟签数量,*拟签含税单价(元)可修改: \r\n2、底色标记的价格为该物料行的最低报价: \r\n3、若不中标,将拟签数量及价格空着即可: \r\n4、平台拟签数量最多保留4位小数点、拟签含税单价最多保留4位小数点,可能会造成平台总价计算结果与EXCEL计算略有差异,请以平台页面为准\"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n","CardList": [{"Name": "ZH001","Price": 0.0,"SumPrice": 0.0},{"Name": "ZH002","Price": 0.0,"SumPrice": 0.0}]}
]

调用方法 

/// <summary>
/// 导出特定模板数据.
/// </summary>
/// <param name="tempFileName">模板名称.</param>
/// <param name="listData">模板数据.</param>
/// <returns></returns>
[NonAction]
private async Task<dynamic> ExportTempExcelData(string tempFileName, List<PurQuoteExportDataCrInput> listData)
{//文件服务器地址string addPath = Path.Combine("D:\\TemporaryFile", tempFileName);// 创建一个新的工作簿HSSFWorkbook workbook = new HSSFWorkbook();ISheet sheet = workbook.CreateSheet("定制模版");// 合并列sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, 5));  // 采购信息sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(1, 2, 0, 0));  // 序号sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(1, 2, 4, 4));  // 采购数量sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(1, 2, 5, 5));  // 最低报价// 设置单元格宽度sheet.SetColumnWidth(1, 20 * 256); // 物料名称宽度sheet.SetColumnWidth(2, 20 * 256); // 规格型号宽度// 设置主要样式var cellStyle = SetMainCellStyle();// 创建行var row1 = sheet.CreateRow(0);var row2 = sheet.CreateRow(1);var row3 = sheet.CreateRow(2);// 设置行高row1.Height = 30 * 30;row2.Height = 30 * 20;row3.Height = 30 * 20;// 采购信息标题var row1_cel = row1.CreateCell(0);row1_cel.SetCellValue("采购信息");row1_cel.CellStyle = cellStyle;// 设置边框row1.CreateCell(1).CellStyle = cellStyle;row1.CreateCell(2).CellStyle = cellStyle;row1.CreateCell(3).CellStyle = cellStyle;row1.CreateCell(4).CellStyle = cellStyle;// 序号标题var cell2 = row2.CreateCell(0);cell2.SetCellValue("序号");cell2.CellStyle = cellStyle;// 采购数量标题var row2_cel4 = row2.CreateCell(4);row2_cel4.SetCellValue("采购数量");row2_cel4.CellStyle = cellStyle;// 最低报价标题var row2_cel5 = row2.CreateCell(5);row2_cel5.SetCellValue("最低报价");row2_cel5.CellStyle = cellStyle;// 填充边框row3.CreateCell(0).CellStyle = cellStyle;// 物料名称标题var row3_cel1 = row3.CreateCell(1);row3_cel1.SetCellValue("物料名称");row3_cel1.CellStyle = cellStyle;// 规格型号标题var row3_cel2 = row3.CreateCell(2);row3_cel2.SetCellValue("规格型号");row3_cel2.CellStyle = cellStyle;// 计量单位标题var row3_cel3 = row3.CreateCell(3);row3_cel3.SetCellValue("计量单位");row3_cel3.CellStyle = cellStyle;// 填充边框row3.CreateCell(4).CellStyle = cellStyle;row3.CreateCell(5).CellStyle = cellStyle;// 从第4行开始都是动态数据int startRow4 = 3;// 记录最有一列下标int lastIndex = 0;// 拟签含税总价double sumAmount = 0;// 动态渲染数据for (var i = 0; i < listData.Count; i++){ICellStyle dyCel_Style = SetMainCellStyle(false);var dyRow = sheet.CreateRow(startRow4);dyRow.Height = 30 * 20; // 设置行高var dyCel0 = dyRow.CreateCell(0);dyCel0.SetCellValue(i + 1);  // 序号值dyCel0.CellStyle = dyCel_Style;var dyCel1 = dyRow.CreateCell(1);dyCel1.SetCellValue(listData[i].ItemName);  // 物料名称值dyCel1.CellStyle = dyCel_Style;var dyCel2 = dyRow.CreateCell(2);dyCel2.SetCellValue(listData[i].ItemName);  // 型号规格值dyCel2.CellStyle = dyCel_Style;var dyCel3 = dyRow.CreateCell(3);dyCel3.SetCellValue(listData[i].Uom);  // 计量单位值dyCel3.CellStyle = dyCel_Style;var dyCel4 = dyRow.CreateCell(4);dyCel4.SetCellValue(listData[i].Quantity);  // 采购数量值dyCel4.CellStyle = dyCel_Style;var dyCel5 = dyRow.CreateCell(5);dyCel5.SetCellValue(listData[i].MinPrice);  // 最低报价值dyCel5.CellStyle = dyCel_Style;startRow4++;int startNum = 6;int endNum = 7;// 动态供应商信息从第六列开始遍历数据var cardList = listData[i].CardList;for (int k = 0; k < cardList.Count; k++){if (i == 0){// 合并列sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, startNum, endNum)); // 供应名称sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(1, 2, startNum, startNum)); // 单价sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(1, 2, endNum, endNum)); // 总价// 供应商ICell cell = row1.CreateCell(startNum);cell.SetCellValue(cardList[k].Name);cell.CellStyle = cellStyle;// 填充边框ICell cell1 = row1.CreateCell(endNum);cell1.CellStyle = cellStyle;// 单价标题var row2_cel_num = row2.CreateCell(startNum);row2_cel_num.SetCellValue("单价");row2_cel_num.CellStyle = cellStyle;// 总价标题var row2_cel_num1 = row2.CreateCell(endNum);row2_cel_num1.SetCellValue("总价");row2_cel_num1.CellStyle = cellStyle;// 填充边框row3.CreateCell(startNum).CellStyle = cellStyle;row3.CreateCell(endNum).CellStyle = cellStyle;}// 单价值var row4_cel_num = dyRow.CreateCell(startNum);row4_cel_num.SetCellValue(cardList[k].Price);row4_cel_num.CellStyle = dyCel_Style;// 总价值var row4_cel_num1 = dyRow.CreateCell(endNum);row4_cel_num1.SetCellValue(cardList[k].SumPrice);row4_cel_num1.CellStyle = dyCel_Style;// 供应商单价、总价突出显示if(listData[i].MinPrice == cardList[k].Price && listData[i].MinPrice > 0){ICellStyle style1 = SetMainCellStyle(false);style1.FillForegroundColor = IndexedColors.Red.Index; // 设置背景颜色为红色style1.FillPattern = FillPattern.SolidForeground;     // 填充模式为纯色row4_cel_num.CellStyle = style1;row4_cel_num1.CellStyle = style1;sumAmount += cardList[k].SumPrice;}startNum += 2;endNum = startNum + 1;lastIndex = startNum;}// 使用单位值var dyCeln = dyRow.CreateCell(lastIndex);dyCeln.SetCellValue("使用单位" + i);dyCeln.CellStyle = dyCel_Style;}// 处理边框var row1_cel_last = row1.CreateCell(lastIndex);row1_cel_last.CellStyle = cellStyle;var row2_cel_last = row2.CreateCell(lastIndex);row2_cel_last.CellStyle = cellStyle;var row3_cel_last = row3.CreateCell(lastIndex);row3_cel_last.CellStyle = cellStyle;row3_cel_last.SetCellValue("使用单位");// 合并拟签含税总价sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(startRow4, startRow4, 0, lastIndex - 1));// 合并备注sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(startRow4 + 1, startRow4 + 1, 0, lastIndex - 1));// 设置合并拟签含税总价var row_sprice = sheet.CreateRow(startRow4);row_sprice.Height = 30 * 15;var cell_sprice = row_sprice.CreateCell(0);cell_sprice.SetCellValue("拟签含税总价:" + sumAmount);ICellStyle cell_sprice_style = SetMainCellStyle();cell_sprice_style.Alignment = HorizontalAlignment.Left; // 垂直靠左cell_sprice.CellStyle = cell_sprice_style;// 设置备注var row_desc = sheet.CreateRow(startRow4 + 1);row_desc.Height = 30 * 50;var cell_desc = row_desc.CreateCell(0);cell_desc.SetCellValue(listData[0].Desc);ICellStyle cell_desc_style = SetMainCellStyle();cell_desc_style.Alignment = HorizontalAlignment.Left; // 垂直靠左var cell_desc_style_font = workbook.CreateFont();cell_desc_style_font.FontName = "SimSun";cell_desc_style_font.FontHeightInPoints = 8; // 设置字体大小cell_desc_style_font.Color = HSSFColor.Red.Index; // 设置字体颜色cell_desc_style.SetFont(cell_desc_style_font);cell_desc.CellStyle = cell_desc_style;// 处理合并拟签含税总价样式、备注样式其余边框for (var i = 1; i < lastIndex + 1; i++){ICellStyle cellStyle2 = workbook.CreateCellStyle();SetCellBorder(cellStyle2);row_sprice.CreateCell(i).CellStyle = cellStyle2;row_desc.CreateCell(i).CellStyle = cellStyle2;}MemoryStream fileStream = new MemoryStream();workbook.Write(fileStream);fileStream.Position = 0; // 确保流的位置重置为0//文件上传到服务器本地await _fileManager.UploadFileByType(fileStream, FileVariable.TemporaryFilePath, tempFileName);//返回文件下载地址前端调用下载return new { name = tempFileName, url = "/api/file/Download?file=" + tempFileName ) };// 设置单元格边框void SetCellBorder(ICellStyle _cellStyle){// 设置单元格边框样式_cellStyle.BorderTop = BorderStyle.Thin;   // 上边框_cellStyle.BorderBottom = BorderStyle.Thin; // 下边框_cellStyle.BorderLeft = BorderStyle.Thin;   // 左边框_cellStyle.BorderRight = BorderStyle.Thin;  // 右边框// 设置边框颜色黑色_cellStyle.TopBorderColor = IndexedColors.Black.Index;_cellStyle.BottomBorderColor = IndexedColors.Black.Index;_cellStyle.LeftBorderColor = IndexedColors.Black.Index;_cellStyle.RightBorderColor = IndexedColors.Black.Index;}// 设置主要样式ICellStyle SetMainCellStyle(bool fontBold = true){// 创建单元格样式ICellStyle cellStyle = workbook.CreateCellStyle();SetCellBorder(cellStyle);// 创建字体样式var font = workbook.CreateFont();font.IsBold = fontBold; // 设置字体加粗font.FontName = "SimSun"; // 设置宋体cellStyle.SetFont(font);cellStyle.Alignment = HorizontalAlignment.Center; // 水平居中cellStyle.VerticalAlignment = VerticalAlignment.Center; // 垂直居中cellStyle.WrapText = true;   // 自动换行return cellStyle;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/61135.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSDN如何写出”爆款“文章

一、选题策划 关注热点与趋势 时常浏览技术领域的热门话题&#xff0c;比如通过关注各大科技资讯网站&#xff08;如 InfoQ、开源中国等&#xff09;、社交媒体上的技术大 V 动态、行业知名企业发布的技术博客等渠道&#xff0c;了解当下最受关注的编程语言更新、框架应用、新兴…

DAY113代码审计-PHPTP框架微P系统漏审项目等

一、环境安装 导入数据 Debug 版本信息收集 一、不安全写法的sql注入&#xff08;拼接写法绕过预编译机制&#xff09; 1、Good.php的不安全写法 2、查找可以参数 3、找路由关系 application/index/controller/Goods.php http://172.19.1.236:8833/index.php/index/goods/aj…

Flink1.19编译并Standalone模式本地运行

1.首先下载源码 2.本地运行 新建local_conf和local_lib文件夹&#xff0c;并且将编译后的文件放入对应的目录 2.1 启动前参数配置 2.1.2 StandaloneSessionClusterEntrypoint启动参数修改 2.1.3 TaskManagerRunner启动参数修改 和StandaloneSessionClusterEntrypoint一样修改…

Ascend C算子性能优化实用技巧05——API使用优化

Ascend C是CANN针对算子开发场景推出的编程语言&#xff0c;原生支持C和C标准规范&#xff0c;兼具开发效率和运行性能。使用Ascend C&#xff0c;开发者可以基于昇腾AI硬件&#xff0c;高效的实现自定义的创新算法。 目前已经有越来越多的开发者使用Ascend C&#xff0c;我们…

传奇996_23——杀怪掉落,自动捡取,捡取动画

一、杀怪掉落 前置&#xff1a; 添加地图地图刷怪怪物掉落&#xff08;术语叫爆率&#xff0c;掉落叫爆率&#xff0c;而且文档上叫爆率&#xff09; 刷怪步骤&#xff1a;在\MirServer\Mir200\Envir\MonItems文件夹中建立以怪物名字为文件名的txt文件写法案例&#xff1a; …

第二十四章 TCP 客户端 服务器通信 - 当前 TCP 设备

文章目录 第二十四章 TCP 客户端 服务器通信 - 当前 TCP 设备当前 TCP 设备TCP 设备的 USE 命令 第二十四章 TCP 客户端 服务器通信 - 当前 TCP 设备 当前 TCP 设备 可以使用 %SYSTEM.TCPDevice方法返回当前 TCP 设备的 IP 地址和端口号。可以使用 Help() 方法列出这些方法&a…

计算机编程中的测试驱动开发(TDD)及其在提高代码质量中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 计算机编程中的测试驱动开发&#xff08;TDD&#xff09;及其在提高代码质量中的应用 计算机编程中的测试驱动开发&#xff08;T…

前后端交互之动态列

一. 情景 在做项目时&#xff0c;有时候后会遇到后端使用了聚合函数&#xff0c;导致生成的对象的属性数量或数量不固定&#xff0c;因此无法建立一个与之对应的对象来向前端传递数据&#xff0c;这时可以采用NameDataListVO向前端传递数据。 Data Builder AllArgsConstructo…

[笔记]L6599的极限工作条件考量

0.名词 OTP over tempature protect.OCP over current protectOVP over voltage protectBrownout Protection Undervoltage Protection可能需要考虑hysteresis response.因为要考虑一些高频干扰 1.基本的过流保护逻辑 参考&#xff1a;ST L6599 器件手册 LLC开关电源&#…

shell编程规范和脚本变量

什么是shell 人和计算机内核之间的中介&#xff1a; 计算机的语言是二进制&#xff0c;把人类的语言翻译成计算机能够识别的语言&#xff0c;然后让内核来处理 内核完成之后要把结果反馈给用户&#xff0c;要把计算机的翻译成人类能够识别的语言 命令解释器&#xff0c;pyc…

二分查找类型算法

今天开始刷题啦&#xff0c;坚持住哟&#xff01; 使用二分法的前提是数组有序且无重复元素。 704.二分查找 第一遍代码如下&#xff1a; class Solution {public int search(int[] nums, int target) {int left0;int rightnums.length-1;while(left<right){int mid (r…

【Pikachu】XML外部实体注入实战

若天下不定&#xff0c;吾往&#xff1b;若世道不平&#xff0c;不回&#xff01; 1.XXE漏洞实战 首先写入一个合法的xml文档 <?xml version "1.0"?> <!DOCTYPE gfzq [<!ENTITY gfzq "gfzq"> ]> <name>&gfzq;</name&…

多模块集成swagger(knife4j-spring-boot-starter)

前言 单体项目、多模块单体项目、微服务项目&#xff0c;集成的方案大同小异&#xff0c;微服务会在网关做个聚合&#xff0c;后面再补充。 依赖版本 目前demo的版本如下&#xff1a; spring boot 2.7.3spring cloud 2021.0.4spring cloud alibaba 2021.0.4.0knife4j-sprin…

uni-app快速入门(七)--组件路由跳转和API路由跳转及参数传递

uni-app有两种页面路由跳转模式&#xff0c;即使用navigator组件跳转和调用API跳转&#xff0c;API调转不要理解为调用后台接口的API&#xff0c;而是指脚本函数中使用跳转函数。 一、组件路由跳转 1.1 打开新页面 打开新页面使用组件的open-type"navigate",见下面…

DataStream编程模型之数据源、数据转换、数据输出

Flink之DataStream数据源、数据转换、数据输出&#xff08;scala&#xff09; 0.前言–数据源 在进行数据转换之前&#xff0c;需要进行数据读取。 数据读取分为4大部分&#xff1a; &#xff08;1&#xff09;内置数据源&#xff1b; 又分为文件数据源&#xff1b; socket…

CSS盒子的定位>(上篇)#定位属性#相对定位-附练习

一、定位属性 1.定位方式 position属性可以选择4种不同类型的定位方式。 语法格式&#xff1a;position&#xff1a;relation | absolute | fixed参数&#xff1a;①relative生成相对定位的元素&#xff0c;相对于其正常位置进行定位。 ②absolute生成绝对定位的…

django从入门到精通(六)——auth认证及自定义用户

Django 提供了一个强大的用户认证系统&#xff0c;允许开发者轻松管理用户的注册、登录、权限和组等功能。以下是对 Django 用户认证系统的详细介绍&#xff0c;包括默认的用户认证、自定义用户认证和权限设置。 1. 默认用户认证 1.1 用户模型 Django 默认提供了一个用户模型…

Redis/Codis性能瓶颈揭秘:网卡软中断的影响与优化

目录 现象回顾 问题剖析 现场分析 解决方案 总结与反思 1.调整中断亲和性&#xff08;IRQ Affinity&#xff09;&#xff1a; 2.RPS&#xff08;Receive Packet Steering&#xff09;和 RFS&#xff08;Receive Flow Steering&#xff09;&#xff1a; 近期&#xff0c;…

MySQL 中有哪几种锁?

在 MySQL 中&#xff0c;锁&#xff08;Locks&#xff09;是为了保证数据的一致性和完整性而设计的机制。常见的锁可以从粒度和操作类型两个角度分类。以下是详细介绍&#xff1a; 按 粒度 分类 1. 全局锁 描述&#xff1a;锁定整个数据库实例。用途&#xff1a;主要用于备份…

重置docker版本的octoprint管理员账号密码

我的情况是octoprint安装在HiNAS系统的机顶盒上&#xff0c;只有一个账号&#xff0c;但是忘记了用户名和密码。有两个选择&#xff1a; 可以试试先找回用户名&#xff0c;然后尝试你的常用密码。直接重置所有账号。 1.找回用户名&#xff1a; 使用使用 docker exec -it <…