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;}
相关文章:

NPOI 实现Excel模板导出
记录一下使用NPOI实现定制的Excel导出模板,已下实现需求及主要逻辑 所需Json数据 对应参数 List<PurQuoteExportDataCrInput> listData [{"ItemName": "电缆VV3*162*10","Spec": "电缆VV3*162*10","Uom":…...

【OpenGL】OpenGL简介
文章目录 OpenGL概述OpenGL的本质OpenGL相关库核心库窗口管理glutfreeglutglfw 函数加载glewGLAD OpenGL概述 OpenGL(Open Graphics Library) 严格来说,本身并不是一个API,它是一个由Khronos组织制定并维护的规范(Specification)。OpenGL规范严格规定了…...
shell命令笔记
一、shell基本基础知识 1. shell命令中捕获上一个命令执行是否成功,通过判断 $? 是否为0,为0则表示成功,其他错误码则表示执行失败。 2. sheel命令中,变量赋值时默认都是字符串类型。赋值时须注意单引号与双引号的区别…...
qml显示OpenCV mat图片
文章目录 方式一QQuickPaintedItem 类介绍主要特点使用方法示例代码在 QML 中使用主要方法和属性注意事项编写OpenCV mat显示代码方式二本篇博客介绍在Qt6.5.3 qml项目里介绍如何显示OpenCV mat图片。视频:https://edu.csdn.net/learn/40003/654043?spm=3001.4143 在qml里显示…...

类与对象(2)---类的6个默认成员函数
1.类的6个默认成员函数 任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。 2.构造函数 2.1构造函数特性 构造函数的主要任务是初始化对象。 它有如下特…...

华为云租户网络-用的是隧道技术
1.验证租户网络是vxlan 2.验证用OVS 2.1控制节点VXLAN 本端ip(local ip)192.168.31.8 2.2计算节点VXLAN 本端ip(local ip)192.168.31.11 计算节点用的是bond0做隧道网络 2.3查看bond文件是否主备模式...

手搓神经网络(MLP)解决MNIST手写数字识别问题 | 数学推导+代码实现 | 仅用numpy,tensor和torch基本计算 | 含正反向传播数学推导
手写数字识别(神经网络入门) 文章目录 手写数字识别(神经网络入门)实验概述实验过程数据准备模型实现线性变换层前向传播反向传播更新参数整体实现 激活函数层(ReLU)前向传播反向传播整体实现 Softmax层&am…...

esp32c3安装micropython环境
esp32c3竟然支持micropython环境,真的太让人高兴了。主要是python开发比较友好,开发速度要快于C和C, 可以用来快速创意验证。 下载 首先到官网:MicroPython - Python for microcontrollers 点击“download”进入下载页面&#…...
ES6的Iterator 和 for...of 循环
写在前面 在JavaScript中,Iterator(遍历器)是一种接口,用于遍历数据结构(如数组、对象等)中的元素。它提供了一种统一的方式来访问集合中的每个项,包括值和位置。 默认 Iterator 接口 许多内…...
《C语言程序设计现代方法》note-4 基本类型 强制类型转换 类型定义
文章目录 助记提要7章 基本类型7.1 整数类型有符号整数和无符号整数整数类型的说明符整数类型的范围整型常量整数溢出读/写整数 7.2 浮点类型浮点数的范围浮点常量读/写浮点数 7.3 字符类型字符被当做整数来操作转义序列大小写转换scanf和printf读/写字符getchar和putchar读写字…...
MySQL(4)【数据类型 —— 数值类型】
阅读导航 引言一、数据类型分类二、数值类型取值范围三、tinyint 类型1. 💻数值越界测试⭕有符号案例⭕无符号案例 四、bit 类型1. 基本语法2. 使用示例✅创建表并插入数据✅使用 BIT 存储多个设置✅查询和格式化 BIT 数据✅更新 BIT 数据 五、小数类型1. float&…...

Golang超详细入门教程
Golang超详细入门教程 部分图片可能加载不出来,所以这里我上传到了自己的个人网站上也可以查看:http://dahua.bloggo.chat/testimonials/490.html 一、数据类型转换 C语言中数据可以隐式转换或显示转换, 但是Go语言中数据只能显示转换格式: 数据类型(…...

鸿蒙NEXT自定义组件:太极Loading
【引言】(完整代码在最后面) 本文将介绍如何在鸿蒙NEXT中创建一个自定义的“太极Loading”组件,为你的应用增添独特的视觉效果。 【环境准备】 电脑系统:windows 10 开发工具:DevEco Studio NEXT Beta1 Build Vers…...

FPGA 第7讲 简单组合逻辑译码器
时间:2024.11.15 一、学习内容 1.译码器 译码是编码的逆过程,在编码时,每一种二进制代码,都赋予了特定的含义,即都表示了一个确定的信号或者对象。把代码状态的特定含义翻译出来的过程叫做译码,实现译码操…...

opencv kdtree pcl kdtree 效率对比
由于项目中以一个环节需要使用kdtree ,对性能要求比较严苛,所以看看那个kdtree效率高一些。对比了opencv和pcl。 #include <array> #include <deque> #include <fstream> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp…...

1+X应急响应(网络)系统备份:
系统备份: 系统备份概述: 备份种类: 灾难恢复等级划分: 执行一次备份: 创建备份计划: 恢复备份:...
python os.path.dirname(path) 详解
dirname 是一个用于处理文件路径的 Python 函数,通常用于获取给定路径的目录部分。它是 os.path 模块中的一部分。下面是对 dirname 函数的详细解释和使用示例。 1、导入模块 首先,你需要导入 os 模块,因为 dirname 是 os.path 模块的一部分…...
深度解析 Feign
一、引言 在当今微服务架构盛行的时代,众多微服务相互协作构成了复杂的分布式系统。然而,各个微服务之间的调用往往涉及到诸多繁琐的细节,比如网络请求的构建、参数的处理、响应的解析等。为了让开发人员能够更加专注于业务逻辑的实现&#x…...

AI工业大模型报告:体系架构、关键技术与典型应用
研究意义 随着新一代人工智能的发展, 大模型(如 GPT-4o 等)凭借大规模训练数据、网络参数和算 力涌现出强大的生成能力、泛化能力和自然交互能力, 展现出改变工业世界的巨大潜力. 尽管大模型 已在自然语言等多个领域取得突破性进展, 但其在工业应用中的…...

深入理解接口测试:实用指南与最佳实践5.0(五)
✨博客主页: https://blog.csdn.net/m0_63815035?typeblog 💗《博客内容》:.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 📢博客专栏: https://blog.csdn.net/m0_63815035/cat…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...