数据转换为excel模板下载

 一、引入依赖

<dependency><groupId>org.jxls</groupId><artifactId>jxls-poi</artifactId><version>2.12.0</version></dependency>

二、准备解析的数据封装 

package com.dst.modules.business.after.sale.parts.sparepartsprocurepo.service;import com.dst.common.util.ConvertCNMoneyUtils;
import com.dstcar.common.utils.date.DateUtil;
import com.dstcar.common.utils.spring.BeanUtil;
import com.dstcar.entitys.sparepartsprocurepo.*;
import lombok.extern.slf4j.Slf4j;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;@Slf4j
@Component
public class SparePartsProcurePoQuoteTemplateRender {private Resource spTemplate;@PostConstructprotected void init() {ResourceLoader resourceLoader = new DefaultResourceLoader();spTemplate = resourceLoader.getResource("classpath:/templates/excelTemp/SparePartsProcurePoQuoteTemplate.xlsx");}/*** 渲染* @param os    输出流*/public void render(SparePartsProcurePoDTO procurePoDTO, OutputStream os) {try (InputStream is = spTemplate.getInputStream()) {Context context = new Context();context.putVar("data", buildData(procurePoDTO));JxlsHelper.getInstance().processTemplate(is, os, context);} catch (Exception e) {log.error("采购订单模版渲染异常", e);}}private SpareParsProcurePoQuoteTemplateData buildData(SparePartsProcurePoDTO procurePoDTO) {final SpareParsProcurePoQuoteTemplateData templateData = new SpareParsProcurePoQuoteTemplateData();SparePartsProcurePo sparePartsProcurePo = procurePoDTO.getSparePartsProcurePo();BeanUtil.copyProperties(sparePartsProcurePo,templateData);List<SparePartsProcurePoDetail> procurePoDetailList = procurePoDTO.getProcurePoDetailList();AtomicReference<Integer> i = new AtomicReference<>(1);final List<SpareParsProcurePoQuoteSkuTemplateData> skuTemplateData = procurePoDetailList.stream().map(pro -> {final SpareParsProcurePoQuoteSkuTemplateData quoteSkuTemplateData = new SpareParsProcurePoQuoteSkuTemplateData();quoteSkuTemplateData.setSequence(i.getAndSet(i.get() + 1));BeanUtil.copyProperties(pro, quoteSkuTemplateData);return quoteSkuTemplateData;}).sorted(Comparator.comparing(SpareParsProcurePoQuoteSkuTemplateData::getSequence)).collect(Collectors.toList());//大小写金额转换templateData.setTotalAmountStr(ConvertCNMoneyUtils.toChinese(String.valueOf(templateData.getTotalAmount())));templateData.setTotalPurchaseQuantity(skuTemplateData.stream().map(SpareParsProcurePoQuoteSkuTemplateData::getPurchaseQuantity).reduce(BigDecimal.ZERO, BigDecimal::add));templateData.setOrderTime(DateUtil.convert2String(sparePartsProcurePo.getOrderTime(), DateUtil.DATEFORMAT));templateData.setContractCode(procurePoDetailList.get(0).getContractCode());templateData.setDetails(skuTemplateData);return templateData;}}

三、对应导出excel数据的实体类

1.订单主档

package com.dstcar.entitys.sparepartsprocurepo;import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;import java.math.BigDecimal;
import java.util.List;@Data
public class SpareParsProcurePoQuoteTemplateData {/** 采购订单号 规则:CGDD+日期+流水号,按日期累加 **/private String orderCode;/** 订单日期 **/@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")private String orderTime;/** 甲方名称 **/private String partyAName;/** 乙方名称 **/private String partyBName;/** 需方授权代表 **/private String demandAgent;/** 供方授权代表 **/private String supplierAgent;/** 需方地址 **/private String demandAddress;/** 供方地址 **/private String supplierAddress;/** 需方联系方式 **/private String demandContactsStyle;/** 供方联系方式 **/private String supplierContactsStyle;/** 结算方式:1月结30天|2月结60天|3月结90天|4先款后货(字典:spare_parts_payment_method) **/private String paymentMethodName;/** 发票类型:1增值税发票2普通发票(字典:spare_parts_po_invoice_type) **/private String invoiceTypeName;/** 订单总额(产品明细含税总额合计【含税总额(含税单价unitPriceIncludeTax * 采购数量purchaseQuantity)】) **/private BigDecimal totalAmount;/*** 订单总额大写文字*/private String totalAmountStr;/*** 总的采购数量*/private BigDecimal totalPurchaseQuantity;/** 备注 **/private String remark;/** 关联合同号 **/private String contractCode;/** po订单明细 */private List<SpareParsProcurePoQuoteSkuTemplateData> details;}

2.订单明细实体

package com.dstcar.entitys.sparepartsprocurepo;import com.dstcar.common.translation.Translation;
import lombok.Data;import java.math.BigDecimal;@Data
public class SpareParsProcurePoQuoteSkuTemplateData {/*** 序号*/private Integer sequence;/** 零配件编码,逗号分割 **/@Translation(convertName = "partsMaterialNameBatchConvert", convertTo = {"materialCodes-materialName"})private String materialCodes;/*** 物料名称*/private String materialName;/** 零配件规格 */private String specs;/** 计量单位 */private String productUnitName;/** 采购数量 **/private BigDecimal purchaseQuantity;/** 含税单价 **/private BigDecimal unitPriceIncludeTax;/** 税率 **/private BigDecimal taxRate;/** 含税总额(含税单价*采购数量) **/private BigDecimal includeTotalAmount;/** 收货人 **/private String receivedPerson;/** 收货人联系电话 **/private String receivedPhone;/** 收货人地址 **/private String receivedAddress;/** 备注 **/private String remark;}

3.转化为导出url路径

/*** 下载po订单模板接口* @param id* @return*/public Results downloadOrder(String id,SSOUser ssoUser) {SparePartsProcurePoDTO procurePoDTO = this.getProcurePoDetailById(id);Integer priceSource = procurePoDTO.getProcurePoDetailList().get(0).getPriceSource();// 渲染ByteArrayOutputStream outputStream = new ByteArrayOutputStream();if (SparePartsFirmConstant.PRICE_SOURCE_2.equals(priceSource) ||SparePartsFirmConstant.PRICE_SOURCE_1.equals(priceSource) ||SparePartsFirmConstant.PRICE_SOURCE_4.equals(priceSource)) {sparePartsProcurePoCatalogTemplateRender.render(procurePoDTO, outputStream);} else if (SparePartsFirmConstant.PRICE_SOURCE_3.equals(priceSource) ||SparePartsFirmConstant.PRICE_SOURCE_5.equals(priceSource) ){sparePartsProcurePoQuoteTemplateRender.render(procurePoDTO, outputStream);} else {log.error("价格来源类型不存在:{}",priceSource);sparePartsProcurePoQuoteTemplateRender.render(procurePoDTO, outputStream);}// 上传ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());String fileName = getFileName();final String aliObjName = genAliObjName(fileName);final String fileUrl = aliOSSStoreClient.uploadFile(inputStream, aliObjName, fileName);log.info("渲染采购订单模板并上传路径:{}, 文件名:{}", aliObjName, fileName);uploadExcel(AliOSSHelper.getAccessUrl(fileUrl),fileName,ssoUser);return succeed();}/*** 生成订单附件文件* @return*/private String getFileName() {return "易维&供应商名称-采购订单" + ".xlsx";}/*** 生成文件上传路径* @return*/private String genAliObjName(String FileName) {return "/operate/spare/parts/procure/po/template/"+dstIdUtils.getPrimaryKey()+"/" + FileName;}/**** @param url* @param fileName*/public  void uploadExcel(String url, String fileName, SSOUser ssoUser){Date date = new Date();ExportRecord exportRecord = new ExportRecord();exportRecord.setFileUrl(url);exportRecord.setFileName(fileName);exportRecord.setModule(10);exportRecord.setModuleName("零配件采购订单");//处理完成exportRecord.setStatus(2);exportRecord.setSource(0);exportRecord.setFileClassification(0);exportRecord.setRequestMethod("GET");exportRecord.setServerName("dst-operate-basic-api");exportRecord.setFileType(FileTypeConstant.EXCEL_2007);exportRecord.setCreateUserId(ssoUser.getId());exportRecord.setCreateUserName(ssoUser.getRealname());exportRecord.setCreateTime(date);exportRecord.setUpdateUserId(ssoUser.getId());exportRecord.setUpdateUserName(ssoUser.getRealname());exportRecord.setUpdateTime(date);exportRecordService.save(exportRecord);}

 4.导出订单模板填充

采 购 订 单
签订时间:${data.orderTime}订单编号:${data.orderCode}
需方(甲方):${data.partyAName}供方(乙方):${data.partyBName}
授权代表:${data.demandAgent}授权代表:${data.supplierAgent}
地址:${data.demandAddress}地址:${data.supplierAddress}
联系方式:${data.demandContactsStyle}联系方式:${data.supplierContactsStyle}
经双方友好协议确认,根据下列条款订立本合同:
一、内容:(甲方向乙方订购以下货物):
序号物料名称物料编码物料规格及描述单位数量单价(元)
含税
税率(%)金额(元)
含税
收货人收货人联系方式收货地址备注(交期)
${detail.sequence}${detail.materialName}${detail.materialCodes}${detail.specs}${detail.productUnitName}${detail.purchaseQuantity}${detail.unitPriceIncludeTax}${detail.taxRate}${detail.includeTotalAmount}${detail.receivedPerson}${detail.receivedPhone}${detail.receivedAddress}${detail.remark}
货款合计(大写):(含税费及运费)${data.totalAmountStr} ${data.totalPurchaseQuantity}小写合计${data.totalAmount}    
备注交付时间由甲乙双方书面确认。
二、结算方式:${data.paymentMethodName}
三、订单有效期:
四、质保期:
五、包装标准和要求:物品的包装除可靠保护内存物品外,必须整洁完好,并符合国内各地常规仓储条件的包装要求;外标识清晰正确,并与送货单所示内容一致,乙方应按照包装要求进行包装,并承担运费。甲方应自收到上述物料之日起【2】个工作日内完成上述物料的清点及验收。甲方对乙方上述物料的验收仅视为对其数量、规格、外包装等确认,不代表对物料质量的确认。
六、质量要求与交付期限要求:乙方保证货品质量和品质符合甲方要求,按甲方技术要求、图纸成封样为准,产品封样后未经甲方书面许可,乙方不可擅自更改任何材料和生产工艺、否则导致所供产品质量下降,最终使产品质量下降而需蒙受重大损失(包括:人员全检损失、特采损失,返工更换等待损失、甲方客户退货损失等),乙方要承担造成甲方损失的全部责任,质量不满足要求的,甲方有权要求乙方免费退换物料,乙方需按照本订单约定的交付时间完成物料交付,如因乙方未正常交货影响甲方整个项目进程的,乙方需承担本订单总金额50%的违约责任,违约金不足以弥补甲方损失的,乙方还应继续承担损害赔偿责任。
七、其他约定:

1)甲乙任何一方因不可抗力原因不能履行合同,应及时向对方通报并提供证明,以减轻可能给对方造成的损失。
2)产品交付前产品所有权由乙方保留,产品灭失及损坏风险由乙方承担。产品交付后产品所有权由甲方保留,产品灭失和损坏风险由甲方承担。但所有权和风险转移并不免除乙方对由于其自身原因其或产品固有缺陷导致的产品故障、损坏或灭失所应承担的责任。
3)乙方同意若甲方购买产品后质保期内因产量质量本身问题所产生的需要进行售后或者维修等事项,乙方应积极响应,并应免费为甲方退还或进行维修售后处理。
4)甲乙双方因履行本订单如发生纠纷,当事人双方应当及时协商解决,如协商不成,任何一方均有权向需方所在地人民有管辖权的人民法院提起诉讼。
5)本订单自甲乙双方签字盖章之日起生效,本订单执行期内,甲乙双方均不得随意变更或解除本订单,如有未尽事宜,须经双方共同协商,作出补充规定,补充规定与本订单具有同等法律效力。
6)本订单正本一式两份,甲乙双方各执一份,经双方盖章生效,传真件与原件同等有效,手写或更改无效。
甲 方乙 方
甲 方(盖章): ${data.partyAName}乙 方(盖章): ${data.partyBName}
授权代表(签字):授权代表(签字):

四、效果预览

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

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

相关文章

Mac M1通过homebrew安装Redis报错(perl: unknown or unsupported macOS version: :dunno)

〇、解决方案 升级homebrew&#xff0c;命令如下&#xff1a; brew update-reset一、问题现象 通过命令brew install redis安装Redis&#xff0c;异常如下&#xff1a; fatal: not in a git directory Warning: No remote origin in /opt/homebrew/Library/Taps/homebrew/h…

【OCR】合同上批量贴印章

一、需求 OCR算法在处理合同等文件时&#xff0c;会由于印章等遮挡导致文本误识别。因此在OCR预处理时&#xff0c;有一个很重要的步骤是“去除印章”。其中本文主要聚焦在“去除印章”任务中的数据构建步骤&#xff1a;“合同伪印章”的数据构建。下面直接放几张批量合成后效果…

Godot 添加信号

前言 Godot 里面C#和GDScirpt 的用法完全不一样&#xff0c;网上相关资料太少了。 什么是信号 信号分为信号源&#xff0c;触发&#xff0c;目的节点。信号源在某些条件下触发信号&#xff0c;比如按钮点击&#xff0c;鼠标悬停等事件 #mermaid-svg-wyr9ARVcBFmUUu8y {font-…

C++ shared_ptr类型转换的实现原理与type traits类型萃取

思考下面这个问题&#xff1a; #include <memory> #include <iostream> using namespace std;class A{ public:int data; };class B : public A{ };template <typename _Ty> class TypeCast{ };int main() {shared_ptr<B> b make_shared<B>();…

做了个 chrome 插件实现 B 站视频截图功能,直接从当前视频帧无损复制

起因是看 B 站视频想截个图很麻烦&#xff0c;右下角暂停按钮无法去除&#xff0c;于是写了一行代码把暂停按钮隐藏。 后经提醒&#xff0c;发现可以通过 canvas 获取视频帧来截取图片&#xff0c;于是写了如下代码完美获取视频帧。 var v document.querySelector(".bpx…

从Django模型创建复合索引

目录 什么是复合索引&#xff1f;在Django中创建复合索引示例说明 什么是复合索引&#xff1f; 复合索引是由多个列组成的索引&#xff0c;在数据库中使用多个列的值作为索引键。相比于单个列的索引&#xff0c;复合索引可以更加精确地过滤数据并提高查询的速度。 通过创建复…

【window10】Dart+Android Studio+Flutter安装及运行

安装Dart SDK安装Android Studio安装Flutter在Android Studio中创建并运行Flutter项目 安装前&#xff0c;请配置好你的jdk环境&#xff0c;准备好你的梯子~ 安装Dart SDK 浅浅了解一下Dart&#xff1a; Dart 诞生于2011年&#xff0c;是由谷歌开发的一种强类型、跨平台的客户…

【java学习】对象的产生(18)

文章目录 1. 初始化赋值2. 匿名对象3. 练习3.1. 习题一3.2. 习题二 4. 总结 1. 初始化赋值 当一个对象被创建时&#xff0c;会对其中各种类型的成员变量自动进行初始化赋值。除了基本数据类型之外的变量类型都是引用类型&#xff0c;如上节的 Person 和前面讲过的数组。 成员…

提取Android盒子dtb文件

概述 最近从某鱼上掏了一个CM201-1 YS的盒子&#xff0c;动手倒腾倒腾&#xff0c;准备安装Armbian&#xff0c;用来做矿机&#xff0c;但该型号的盒子ophub上面没有完全适配的镜像&#xff0c;故而想尝试下&#xff0c;看能否整个适配镜像出来。 操作系统 Windows Linux 工…

【MediaSoup---源码篇】(五)接收RTP数据的处理

通过前面的文章我们可以了解到&#xff0c;当创建好Transport的时候&#xff0c;socket已经建立好。具备了相应的网络传输能力。我们来看一下socket接收到数据是如何处理的。 UdpSocketHandler::OnUvRecv Socket接收数据 inline void UdpSocketHandler::OnUvRecv(ssize_t nr…

TDengine时序数据库学习使用

数据库要求&#xff1a; 1.目前服务器只能在linux运行&#xff0c;先安装服务器版本v1 2.下载与v1完全匹配的客户端版本v1&#xff08;客户端与服务器的版本号不匹配可能访问不了服务器&#xff09; 第一步 安装 安装服务器注意&#xff0c;安装教程&#xff1a; 使用安装…

Linux中scp命令复制文件

scp命令是在Linux中用于在本地主机和远程主机之间进行安全传输文件的命令。下面是使用scp命令的语法&#xff1a; scp [参数] [来源路径] [目标路径]参数&#xff1a; -r&#xff1a;递归复制整个目录。-P&#xff1a;指定远程主机的端口。-p&#xff1a;保留原文件的修改时间…

(蓝宝书)网络安全——CTF那些事儿

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

CocosCreator 面试题(七)优化cocos creator 包体体积

优化 Cocos Creator 包体体积是一个重要的任务&#xff0c;可以通过以下几个方面进行优化&#xff1a; 图片文件体积优化&#xff1a; 压缩图片&#xff1a;使用工具如 TinyPNG、ImageOptim 等对图片进行压缩&#xff0c;减小文件大小而保持可接受的质量。图片格式选择&#…

WPF 控件分辨率自适应问题

WPF 控件分辨率自适应时&#xff0c;我首先想到的是使用ViewBox控件来做分辨率自适应。 ViewBox这个控件通常和其他控件结合起来使用&#xff0c;是WPF中非常有用的控件。定义一个内容容器。ViewBox组件的作用是拉伸或延展位于其中的组件&#xff0c;以填满可用空间&#xff0…

深度学习问答题(更新中)

1. 各个激活函数的优缺点&#xff1f; 2. 为什么ReLU常用于神经网络的激活函数&#xff1f; 在前向传播和反向传播过程中&#xff0c;ReLU相比于Sigmoid等激活函数计算量小&#xff1b;避免梯度消失问题。对于深层网络&#xff0c;Sigmoid函数反向传播时&#xff0c;很容易就…

mp4音视频分离技术

文章目录 问题描述一、分离MP3二、分离无声音的MP4三、结果 问题描述 MP4视频想拆分成一个MP3音频和一个无声音的MP4文件 一、分离MP3 ffmpeg -i C:\Users\Administrator\Desktop\一个文件夹\我在财神殿里长跪不起_完整版MV.mp4 -vn C:\Users\Administrator\Desktop\一个文件…

分布式数据库HBase(林子雨慕课课程)

文章目录 4. 分布式数据库HBase4.1 HBase简介4.2 HBase数据模型4.3 HBase的实现原理4.4 HBase运行机制4.5 HBase的应用方案4.6 HBase安装和编程实战 4. 分布式数据库HBase 4.1 HBase简介 HBase是BigTable的开源实现 对于网页搜索主要分为两个阶段 1.建立整个网页索引&#xf…

如何在 Android 中完成一个 APT 项目的开发?

前言 APT(Annotation Processing Tool)即注解处理器&#xff0c;是一种处理注解的工具。 APT在编译时期扫描处理源代码中的注解&#xff0c;开发中可以根据注解&#xff0c;利用APT自动生成Java代码&#xff0c;减少冗余的代码和手动的代码输入过程&#xff0c;提升了编码效率…

pytest + yaml 框架 -55. raw 不转义模板语法

前言 在yaml 文件中&#xff0c;设置的引用变量语法是${var}, 最近有小伙伴提到一个需求&#xff1a;请求参数的内容需要有特殊符号${var}, 希望不被转义&#xff0c;不要引用变量&#xff0c;直接用原始数据即可。 raw 忽略模板语法 Jinja2提供了 “raw” 语句来忽略所有模…