Jxls 实现动态导出功能

2024-01-18 08:28
文章标签 动态 实现 功能 导出 jxls

本文主要是介绍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”

导出效果

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

这篇关于Jxls 实现动态导出功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/618506

相关文章

Spring IOC的三种实现方式详解

《SpringIOC的三种实现方式详解》:本文主要介绍SpringIOC的三种实现方式,在Spring框架中,IOC通过依赖注入来实现,而依赖注入主要有三种实现方式,构造器注入、Setter注入... 目录1. 构造器注入(Cons编程tructor Injection)2. Setter注入(Setter

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC

Python实现文件下载、Cookie以及重定向的方法代码

《Python实现文件下载、Cookie以及重定向的方法代码》本文主要介绍了如何使用Python的requests模块进行网络请求操作,涵盖了从文件下载、Cookie处理到重定向与历史请求等多个方面,... 目录前言一、下载网络文件(一)基本步骤(二)分段下载大文件(三)常见问题二、requests模块处理

vue基于ElementUI动态设置表格高度的3种方法

《vue基于ElementUI动态设置表格高度的3种方法》ElementUI+vue动态设置表格高度的几种方法,抛砖引玉,还有其它方法动态设置表格高度,大家可以开动脑筋... 方法一、css + js的形式这个方法需要在表格外层设置一个div,原理是将表格的高度设置成外层div的高度,所以外层的div需要

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

Java中List转Map的几种具体实现方式和特点

《Java中List转Map的几种具体实现方式和特点》:本文主要介绍几种常用的List转Map的方式,包括使用for循环遍历、Java8StreamAPI、ApacheCommonsCollect... 目录前言1、使用for循环遍历:2、Java8 Stream API:3、Apache Commons

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫