Jxls 实现动态导出功能

目录

  • 引言
  • 前端页面
  • 后端代码
  • excel模板
  • 导出效果

引言

在实际做项目的过程中,导出报表时需要根据每个人所关注的点不一样,所需导出的字段也不一样,这时后端就需要根据每个所选的字段去相应的报表,这就是本文要讲的动态导出报表。

前端页面

  1. 用户在页面上选择要导出的字段,后端根据所选的字段进行导出
    在这里插入图片描述
  2. 将要导出的所有字段做成字典进行管理方便后端进行转换,具体思路请看后端代码
    在这里插入图片描述
    在这里插入图片描述

后端代码

  1. 请求参数实体 OutOrderParam.java
package com.hw.admin.domain.outer.vo;import com.alibaba.fastjson.JSONObject;
import lombok.Data;import java.util.Date;
import java.util.List;/**1. @Description2. @Author liqinglong3. @DateTime 2022-03-30 19:054. @Version 1.0*/
@Data
public class OutOrderParam {/** 搜索关键字 */private String searchValue;/** 出库单状态 */private Integer status;/** 创建日期 */private Date createDate;/** 扫描条码 */private String scanBarcode;/** 导出字段 */private JSONObject fields;private Integer pageSize;private Integer startIndex;private List<String> exportFields;
}
  1. controller方法
 /*** 出库单导出** @param response* @param request*/@Log(title = "出库单导出", businessType = BusinessType.EXPORT)@GetMapping("exportOutOrderXls")public void downStockExcel(HttpServletResponse response,HttpServletRequest request,OutOrderParam param) throws IOException, NoSuchFieldException, IllegalAccessException {String fileFullName = airOutOrderService.exportOutOrderXls(param);String fileName = fileFullName.split("\\|")[1];FileUtils.downloadFile(fileFullName.split("\\|")[0], fileName, response, request);}
  1. 服务层方法
    接口 IOutOrderService.java
/*** 出库单服务接口* @author liql* @date 2022-03-30 16:29:15*/
public interface IOutOrderService extends IBaseService<OutOrder>  {/*** @Description 服务层导出出库单方法* @param param* @return java.lang.String*/
String exportOutOrderXls(OutOrderParam param) throws NoSuchFieldException, IllegalAccessException;
}

实现类 OutOrderServiceImpl.java

Slf4j
@Service
public class OutOrderServiceImpl extends IBaseServiceImpl<OutOrderMapper, AirOutOrder> implements IOutOrderService {@Overridepublic String exportOutOrderXls(OutOrderParam param) throws NoSuchFieldException, IllegalAccessException {log.info("开始执行导出出库单,返回参数:{}",param);//1、获取参数-导出数据限制条数SysConfig config = new SysConfig();config.setConfigKey("export.excel.count");SysConfig retConfig = configMapper.selectConfig(config);int exportCount = Integer.parseInt(retConfig.getConfigValue());//2、获取导出记录总条数int total = mapper.countOutTotal(param);//3、导出的总条数不能超过限制的总条数total = total > exportCount ? exportCount : total;//4、获取选取的字段,默认导出所有字段List<String> fieldsList = param.getExportFields();//获取字典字段列表List<SysDictData> outFieldList = sysDictTypeService.selectDictDataByType("out_field_list");JSONObject paramObject = new JSONObject();//表头List<String> headerList = new ArrayList();if(ObjectUtils.isEmpty(fieldsList)){fieldsList = new ArrayList<>();for (SysDictData dicData:outFieldList) {paramObject.put(dicData.getDictValue(),1);headerList.add(dicData.getDictLabel());fieldsList.add(dicData.getDictValue());}}else{for (String field: fieldsList) {paramObject.put(field,1);for (SysDictData dicData:outFieldList) {if(field.equals(dicData.getDictValue())){headerList.add(dicData.getDictLabel());break;}}}}param.setFields(paramObject);//5、获取数据字典转换字段//出库状态Map<String,String> statusDictMap = new HashMap();List<SysDictData> statusDictDatas = sysDictTypeService.selectDictDataByType("outbound_status");for(SysDictData dictData : statusDictDatas){statusDictMap.put(dictData.getDictValue(),dictData.getDictLabel());}//出库类型Map<String,String> outTypeMap = new HashMap();List<SysDictData> outTypeDatas = sysDictTypeService.selectDictDataByType("outbound_type");for(SysDictData dictData : outTypeDatas){outTypeMap.put(dictData.getDictValue(),dictData.getDictLabel());}//6、计算分页查询次数//每次查询条数int pageSize = 1000;int totalPage = (total / pageSize) + (total % pageSize > 0 ? 1 : 0);//7、循环查询数据//excel表实际上是一个二维表List<List<Object>> lastResult = new ArrayList<>();param.setPageSize(pageSize);for(int i = 0;i < totalPage;i++){param.setStartIndex(i * pageSize);List<ExportOutOrderVo> outOrderList = mapper.queryExportOutOrderList(param);for(ExportOutOrderVo orderVo:outOrderList){// 出库类型转化为中文orderVo.setOutTypeStr(outTypeMap.get(String.valueOf(orderVo.getOutType())));// 出库状态转化为中文orderVo.setStatusStr(statusDictMap.get(String.valueOf(orderVo.getStatus())));//excel中的一行数据List<Object> rowList = new ArrayList<>();for (String header:fieldsList){Field field = orderVo.getClass().getDeclaredField(header);field.setAccessible(true);if("tabId".equals(header)){//将长整型转化为字符串rowList.add(String.valueOf(field.get(orderVo)));}else if("outTime".equals(header)){//将出库时间格式化Date outTime = (Date) field.get(orderVo);if(ObjectUtils.isEmpty(field.get(orderVo))){rowList.add(field.get(orderVo));}else{rowList.add(DateUtils.formatDate(outTime,"yyyy-MM-dd HH:mm:ss"));}}else{rowList.add(field.get(orderVo));}}lastResult.add(rowList);}}//8、生成exelMap<String, Object> model = new HashMap<>();model.put("cols",headerList);model.put("orders", lastResult);String xlsName = "出库单_"+ DateUtils.formatDate(new Date(),"yyyyMMddHHmmss") + ".xlsx";String filePath = "";String geneXlsName = "";try {String orderFileNameTemp = "exportOutOrder.xlsx";try {filePath = new File(ResourceUtils.getURL("classpath:").getPath()).getParentFile().getParentFile().getParent();filePath += File.separator + "report_file" + File.separator;} catch (FileNotFoundException e) {log.error("执行导出出库单,系统异常:" + e);e.printStackTrace();}File exportFilePath = new File(filePath);if (exportFilePath.exists() == false) {exportFilePath.mkdirs();}geneXlsName = filePath + xlsName;JxlsUtils.geneExcel(orderFileNameTemp, geneXlsName, model);} catch (IOException e) {e.printStackTrace();}log.info("结束执行导出出库单,返回参数:" + geneXlsName);return geneXlsName + "|" + xlsName;}}

mapper OrderInfoSpeMapper.java

public interface OrderInfoSpeMapper extends BaseMapper<OrderInfo> {/*** 查询订单导出列表** @param queryVo 订单查询信息* @return 订单导出列表*/List<OrderExportResultVo> selectOrderListExport(OrderQueryVo queryVo);}

xml OrderInfoSpeMapper.xml

  <resultMap type="com.hw.admin.domain.order.vo.OrderExportResultVo" id="OrderExportResult"></resultMap><!-- 查询订单导出列表 --><select id="selectOrderListExport" parameterType="com.hw.admin.domain.order.vo.OrderQueryVo" resultMap="OrderExportResult">SELECTo.id,o.cust_name,o.order_status,o.order_type,o.create_time,o.oper_name,b.address,d.logistics_no,e.id_number,e.contact_phone,f.mat_code,f.goods_name,f.unit_name,sum(f.sale_volume) sale_volume,sum(f.sale_amount) sale_amountFROMair_order_info oLEFT JOIN air_out_order d ON d.tab_id = o.idleft join air_order_receive b on b.order_id = o.idleft join air_customer e on e.id = o.cust_idleft join air_order_goods f on f.order_id = o.id<where>o.del_flag = 0and o.source_type = 0AND o.order_type in (0,1)<if test="searchValue != null and searchValue != ''">AND (o.order_name like concat('%', #{searchValue}, '%')OR o.cust_name like concat('%', #{searchValue}, '%'))</if><if test="beginTime != null and beginTime != ''">AND o.create_time >= STR_TO_DATE(#{beginTime}, '%Y-%m-%d %H:%i:%s')</if><if test="endTime != null and endTime != ''">AND o.create_time &lt;= STR_TO_DATE(#{endTime}, '%Y-%m-%d %H:%i:%s')</if><if test="bottleCode != null and bottleCode != ''">AND exists (select 1from air_out_order_detail e,air_out_good_record fwhere e.order_id = d.idand f.order_detail_id = e.idAND (f.scan_bottlecode like concat('%', #{bottleCode}, '%') OR f.scan_barcode like concat('%', #{bottleCode}, '%')))</if></where>group byo.id,o.cust_name,o.order_status,o.order_type,o.create_time,o.oper_name,b.address,d.logistics_no,e.id_number,e.contact_phone,f.mat_code,f.goods_name,f.unit_nameorder by o.id desc<if test="indexPage != null">LIMIT #{indexPage}, #{sizePage}</if></select>

vo ExportOutOrderVo.java

package com.hw.admin.domain.order.vo;import com.fasterxml.jackson.annotation.JsonFormat;
import com.hw.common.annotation.SensitiveEntity;
import com.hw.common.annotation.SensitiveField;
import lombok.Data;import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;/*** 功能描述: 导出结果信息** @author: liqinglong* @date: 2023/10/9* */
@Data
public class OrderExportResultVo implements Serializable {private static final long serialVersionUID = 1L;/*** 订单id*/private Long id;/*** 订单id*/private String idDesc;/*** 客户名称*/private String custName;/*** 订单状态: 0-审核中 1-待付款 2-待发货 3-待收货 4-已完成 5-售后 6-已关闭 7-酒业出库 8-物流出库*/private Integer orderStatus;/*** 订单状态: 0-审核中 1-待付款 2-待发货 3-待收货 4-已完成 5-售后 6-已关闭 7-出库 8-物流出库*/private String orderStatusDesc;/*** 订单类型 0-普通 1-换货销售*/private Integer orderType;/*** 订单类型 0-普通 1-换货销售*/private String orderTypeDesc;/*** 创建时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime;/*** 创建时间*/private String createTimeDesc;/*** 操作员姓名*/private String operName;/*** 收货地址*/private String address;/*** 运单号*/private String logisticsNo;/*** 身份证号码*/@SensitiveFieldprivate String idNumber;/*** 联系人电话*/@SensitiveFieldprivate String contactPhone;/*** 物料编码*/private String matCode;/*** 商品名称,多个商品名称合并,如飞天茅台等产品*/private String goodsName;/*** 商品单位*/private String unitName;/*** 商品销售数量*/private Long saleVolume;/*** 销售金额*/private BigDecimal saleAmount;/*** 扫描物流条码*/private String scanBarcode;/*** 扫描物流瓶码*/private String scanBottlecode;
}

excel模板

在这里插入图片描述
A1的注解

jx:area(lastCell="A3") //区域范围
jx:mergeCells(cols="cols.size()" lastCell="A1") //标题合并居中

A2的注解

jx:grid(lastCell="A3" headers="cols" data="orders"  areas=["A2:A2,"A3:A3"])

在这里插入图片描述
注意:headers 设置为代码中的key :“cols”, data 设置为代码中的key:“orders”

导出效果

在这里插入图片描述
测试数据,仅供参考

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

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

相关文章

LabVIEW图像识别检测机械零件故障

项目背景&#xff1a; 在工业生产中&#xff0c;零件尺寸的准确检测对保证产品质量至关重要。传统的人工测量方法不仅耗时费力&#xff0c;精度低&#xff0c;还容易导致零件的接触磨损。为了解决这些问题&#xff0c;开发了一套基于LabVIEW和机器视觉的机械零件检测系统。该系…

【Java实战项目】基于ssm的数据结构课程网络学习平台

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Modbus协议学习第三篇之协议通信规则

导语 本篇博客将深入介绍Modbus协议的一些内容&#xff0c;主要包括通讯方式和通讯模型的介绍 Modbus通讯方式 Modbus协议是单主机、多从机的通信协议&#xff0c;即同一时间&#xff0c;总线上只能有一个主设备&#xff0c;但可以有一个或者多个从设备&#xff08;最多好像是2…

STM32F103标准外设库——中断应用/事件控制器(六)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

Java 方法中参数类型后写了三个点?什么意思?

1、...代表什么意思&#xff1f; 2、如何使用 3、注意事项 4、两个list&#xff0c;一个新的&#xff0c;一个旧的&#xff0c;旧列表中可能有新列表中存在的数据&#xff0c;也可能存在新列表中不存在的数据&#xff08;注&#xff1a;新旧列表中都不存在重复元素&#xff09;…

web开发学习笔记(6.element ui)

1.安装 2.在app.vue中引入ElementView中的内容 3.表格控件&#xff0c;当页大小发生变化&#xff0c;当当前页发生变化 4.对话框组件 5.将form表单中的数据打印出来 6.当遇到日期选择器得到的数据为昨日时&#xff0c;应该加入 value-format"yyyy-MM-dd"即可避免这个…

C++学习笔记——C++ 新标准(C++11、C++14、C++17)引入的重要特性

目录 1、简介 2.自动类型推导和初始化 示例代码 3.智能指针 示例代码 4.Lambda 表达式 示例代码 5.右值引用和移动语义 示例代码 6.并发编程支持 示例代码 7.其他特性 八、案例&#xff1a;实现一个简单的并发下载器 上一篇文章&#xff1a; C标准模板库&#xff…

电子雨html代码

废话不多说下面是代码&#xff1a; <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>Code</title><style>body{margin: 0;overflow: hidden;}</style></head><body><c…

mybatis分页、延迟加载、立即加载、一级缓存、二级缓存

mybatis分页、延迟加载、立即加载、一级缓存、二级缓存 分页延迟加载和立即加载缓存一级缓存二级缓存 分页 分类&#xff1a; 使用Limit&#xff0c;来进行分页&#xff1b;物理分页使用RowBounds集合来保存分页需要数据&#xff0c;来进行分页;逻辑分页&#xff1b;本质是全…

Linux/Networked

Enumeration nmap 网站更新之后有了一个引导模式&#xff0c;更利于学习了&#xff0c;之前看ippsec的视频&#xff0c;要不总是没有思路&#xff0c;现在出现的问题多了提示也更多了&#xff0c;还没有使用&#xff0c;一会用用再说 首先&#xff0c;第一个问题是“目标上正…

大数据毕业设计:基于python美食推荐系统+爬虫+Echarts可视化+协同过滤推荐算法+Django框架(源码)✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…

数据结构和算法的部分例题(力扣)

1.数组 1.1 合并一个数组的两个有序区间 public class MargTwo {public static void main(String[] args) {int[] arr1{1,5,6,2,4,10,11};int[] arr2new int[arr1.length];marg2(arr1,0,2,3,6,arr2);}private static void marg2(int[]arr1,int iStar,int iEnd,int jStar,int j…

嵌入式-Stm32-江科大基于标准库的GPIO4个小实验

文章目录 一 、硬件介绍二 、实验&#xff1a;LED闪烁、LED流水灯、蜂鸣器提示2.1 需求1&#xff1a;面包板上的LED以1s为周期进行闪烁。亮0.5s,灭0.5s.....2.2 需求2: 8个LED实现流水灯 三、硬件介绍-按键开关、光敏电阻四、 实验 按键控制LED、光敏传感器控制蜂鸣器4.1 需求1…

【MYSQL】存储引擎MyISAM和InnoDB

MYSQL 存储引擎 查看MySQL提供所有的存储引擎 mysql> show engines; mysql常用引擎包括&#xff1a;MYISAM、Innodb、Memory、MERGE 1、MYISAM&#xff1a;全表锁&#xff0c;拥有较高的执行速度&#xff0c;不支持事务&#xff0c;不支持外键&#xff0c;并发性能差&#x…

ubuntu18.04 安装mysql(命令)

1.安装MySQL #命令1 sudo apt-get update #命令2 sudo apt-get install mysql-server 2.配置MySQL sudo mysql_secure_installation 2.2 检查mysql服务状态 systemctl status mysql.service 3.配置远程访问 在Ubuntu下MySQL缺省是只允许本地访问的 3.1 首先用根用户进入…

深度学习记录--梯度检验

数值逼近 为了对梯度进行检验&#xff0c;需要计算近似误差值来接近梯度 对于单边误差和双边误差公式&#xff0c;其中双边误差与真实梯度相差更小&#xff0c;故一般采用双边误差公式 双边误差 公式&#xff1a; 梯度检验(gradient checking) 对于成本函数&#xff0c;求出…

2018年认证杯SPSSPRO杯数学建模A题(第一阶段)海豚与沙丁鱼全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 探究海豚猎捕时沙丁鱼群的躲避运动模型 A题 海豚与沙丁鱼 原题再现&#xff1a; 沙丁鱼以聚成大群的方式来对抗海豚的捕食。由于水下光线很暗&#xff0c;所以在距离较远时&#xff0c;海豚只能使用回声定位方法来判断鱼群的整体位置&#xf…

旅游平台day02

1. 用户注册 概述&#xff1a; 常见的注册方式&#xff1a;邮箱注册、手机号注册、昵称注册、或者以上几种同时支持 本项目仅仅支持手机号注册 需求&#xff1a; 项目启动后&#xff0c;访问regist.html进入注册页面 手机号校验 前后台都需要对手机号进行校验 前端校验&am…

iOS上h5长按识别图片二维码,图片会默认放大,禁用这一默认行为

iOS上h5长按识别图片二维码&#xff0c;图片会默认放大&#xff0c;禁用这一默认行为 测试代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-widt…

ES可视化工具--ElasticHD

说明 ElasticHD 是 github 上的一个开源的项目&#xff0c;所以他没有官方网站&#xff0c;但 github 上的项目界面也可称为是它的官方界面了。 在 github 上直接搜索 ElasticHD 即可找到它&#xff0c;下面我将留下它的直接跳转链接。ElasticHD 下载 在 github 上搜索到之后…