##需求及思路详解
根据产品及需求,我们需要实现对采购品各分类下的采购品进行导出功能。
(可能会出现的问题):①因为要对采购品各分类下采购品进行导出excel文件的功能,所以要考虑到根目录及子目录下采购品数量及导出的不同。②因为dba对数据要求每次查询不大于8mb,所以要对查询数据进行分批查询。③:文件名乱码问题。④:导入所需jar包到pom文件,因博主是由公司自己封装的esaypoi框架,故在此不列出。
##后台代码实现

##controller层#

    @ApiOperation(value = "导出采购品到Excel文件", httpMethod = "GET")@RequestMapping(value = "downCorpDataByExcel", method = RequestMethod.GET)public void downCorpDataByExcel(@RequestParam(required = false) String name,@RequestParam(required = false) String code,@RequestParam(required = false) String spec,@RequestParam(required = true) Long catalogId,HttpServletResponse response,HttpServletRequest request) {TRegUser user = UserContext.getUser();if (user == null) {logger.warn("获取不到用户信息");return;}CorpDirectorysQueryDto cdQuery = new CorpDirectorysQueryDto();//公司idcdQuery.setCompanyId(user.getCompanyId());//采购品名称模糊查询if (StringUtils.isNotBlank(name)) {cdQuery.setNameLike(name.trim());}//采购品编码模糊查询if (StringUtils.isNotBlank(code)) {cdQuery.setCodeLike(code.trim());}//采购品规格型号模糊查询if (StringUtils.isNotBlank(spec)) {cdQuery.setSpecLike(spec.trim());}//采购品分类id(有前端从tree中获取)if (catalogId != null) {//判断当前目录是否有子目录①   boolean b = corpDirectoryService.hasExistChild(catalogId, user.getCompanyId());logger.info("方法downCorpDataByExcel,公司{}目录{}是否有子目录:{}", user.getCompanyId(), catalogId, b);if (b) {//如果有,查询下当前子目录路径,通过路径去查询采购品列表②   CorpCatalogs corpCatalogs = corpCatalogService.findById(catalogId, user.getCompanyId());//会查询like  CONCAT(#{treepathLike},'%')cdQuery.setTreepathLike(corpCatalogs.getTreepath());} else {cdQuery.setCatalogId(catalogId);}}PageSet pageSet = new PageSet();pageSet.setSortColumn("abandon asc,create_time desc");String corpDataName = "采购品信息.xls";//处理文件名乱码的问题③ corpDataName = encodeDownloadFile(corpDataName, request.getHeader("User-Agent"));response.setHeader("content-disposition", "attachment;filename=" + corpDataName);//根据文件名自动获得文件类型response.setContentType(request.getSession().getServletContext().getMimeType(corpDataName));//告知服务器使用什么编码response.setCharacterEncoding("UTF-8");try {④  HSSFWorkbook workbook = corpDirectoryService.createWorkbook(cdQuery, pageSet);workbook.write(response.getOutputStream());} catch (Exception e) {logger.error("构建excel出错", e);}}

/**判断当前目录是否有子目录
*/
①:

public boolean hasExistChild(Long catalogId, Long companyId) {ServiceResult<Boolean> booleanResult = dubboCorpCatalogsService.hasExistChild(catalogId, companyId);if (!booleanResult.getSuccess()) {logger.error("{}调用{}时发生未知异常,error Message:{}", "cn.bidlink.procurement.materials.app.service.CorpDirectoryService.hasExistChild"," dubboCorpCatalogsService.hasExistChild(catalogId,companyId)", booleanResult.getCode() + "_" + booleanResult.getMessage());throw new RuntimeException("err_code:" + booleanResult.getCode() + ",err_msg:" + booleanResult.getMessage());}Boolean result = booleanResult.getResult();if (result == null) {logger.warn("cn.bidlink.procurement.materials.app.service.CorpDirectoryService.hasExistChild时未获取到结果");}return result;}

/**
如果有子目录,查询下当前子目录路径,通过路径去查询采购品列表
*/
②:

   /*** 获取采购品* @param id* @param companyId* @return*/public CorpCatalogs findById(Long id, Long companyId){if ( id == null || companyId == null ){throw new RuntimeException("参数不能为空");}ServiceResult<CorpCatalogs> findResult = dubboCorpCatalogsService.findByPK(id, companyId);if ( !findResult.getSuccess() ){throw new RuntimeException( findResult.toString() );}return findResult.getResult();}

/**
* 处理文件名乱码的问题 , 不通用
* @param filename 文件名字
* @param agent 浏览器信息
* @return 解决乱码后的文件名
*/
③:

private  String encodeDownloadFile(String filename, String agent){try {if (StringUtils.isNotBlank( agent ) && agent.toUpperCase().indexOf("MSIE") > 0) {filename = URLEncoder.encode(filename, "UTF-8");} else {filename = new String(filename.getBytes("UTF-8"), "ISO8859-1");}} catch (UnsupportedEncodingException e) {logger.error("处理文件名乱码的问题时发生异常",e);}return filename;}

④-1: /**
* 构建采购品数据数据
*
* @param cdQuery 查询对象
* @param pageSet 分页对象
* @return
*/

 public HSSFWorkbook createWorkbook(CorpDirectorysQueryDto cdQuery, PageSet pageSet) {logger.info("方法createWorkbook(CorpDirectorysQueryDto cdQuery,PageSet pageSet)查询采购品数据开始,参数:cdQuery:{}", cdQuery);//先查询所导出的采购品数量ServiceResult<Integer> serviceResult = dubboCorpDirectorysService.getTotal(cdQuery);Integer count = serviceResult.getResult();List<CorpDirectorys> aList = new ArrayList<>();Integer pageSize = 2000;//数量大于2000时,分批查询数据库数据(防止查询数据量太大)if (count >= 2000) {int times = count / pageSize;if (count % pageSize != 0) {times = times + 1;}Integer pageNum = 1;for (int i = 0; i < times; i++) {pageSet.setPageNum(pageNum);pageSet.setPageSize(pageSize);ServiceResult<List<CorpDirectorys>> queryResult = dubboCorpDirectorysService.findByCondition(cdQuery, pageSet);aList.addAll(queryResult.getResult());pageNum++;}} else {//数据量少于2000时直接放入集合ServiceResult<List<CorpDirectorys>> queryResult = dubboCorpDirectorysService.findByCondition(cdQuery, pageSet);logger.info("方法createWorkbook(CorpDirectorysQueryDto cdQuery,PageSet pageSet)查询采购品数据结束");if (!queryResult.getSuccess()) {logger.error("查询数据失败,失败信息:{}", queryResult);throw new RuntimeException("查询数据失败");}aList = queryResult.getResult();}return createCorpDataExcel(aList);}

④-2 /**
* 根据数据生成Excel
*
* @param corpDirectoryList 采购品列表
* @return Excel对象
*/

public HSSFWorkbook createCorpDataExcel(List<CorpDirectorys> corpDirectoryList) {logger.info("方法createCorpDataExcel(List<CorpDirectorys> corpDirectoryList)构建Excel对象开始");// 在内存中创建一个Excel文件,通过输出流写到客户端提供下载HSSFWorkbook workbook = new HSSFWorkbook();//设置文字的样式HSSFCellStyle cellStyle = workbook.createCellStyle();cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);HSSFFont font = workbook.createFont();//HSSFColor.VIOLET.index //字体颜色font.setColor(HSSFColor.BLACK.index);font.setFontHeightInPoints((short) 12);// 创建一个sheet页HSSFSheet sheet = workbook.createSheet("采购品信息");// 创建标题行HSSFRow headRow = sheet.createRow(0);headRow.createCell(0).setCellValue("采购品编码");headRow.createCell(1).setCellValue("采购品名称");headRow.createCell(2).setCellValue("规格型号");headRow.createCell(3).setCellValue("技术参数");headRow.createCell(4).setCellValue("计量单位");headRow.createCell(5).setCellValue("所在分类");headRow.createCell(6).setCellValue("用途");headRow.createCell(7).setCellValue("计划单价");headRow.createCell(8).setCellValue("备注");headRow.createCell(9).setCellValue("状态");//插入采购品数据for (CorpDirectorys corpDirectorys : corpDirectoryList) {HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);//采购品编码dataRow.createCell(0).setCellValue(corpDirectorys.getCode());dataRow.createCell(1).setCellValue(trim(corpDirectorys.getName()));//采购品名称dataRow.createCell(2).setCellValue(trim(corpDirectorys.getSpec()));//规格/型号dataRow.createCell(3).setCellValue(trim(corpDirectorys.getTechParameters()));//技术参数/材质dataRow.createCell(4).setCellValue(trim(corpDirectorys.getUnitName()));//计量单位dataRow.createCell(5).setCellValue(trim(corpDirectorys.getCatalogName()));//所在分类dataRow.createCell(6).setCellValue(trim(corpDirectorys.getPurpose()));//用途dataRow.createCell(7).setCellValue(trim(corpDirectorys.getMarketPrice()));//计划单价dataRow.createCell(8).setCellValue(trim(corpDirectorys.getDemo()));//备注dataRow.createCell(9).setCellValue(CorpDirectorysAbandonEnum.ENABLE.getValue() == corpDirectorys.getAbandon() ? "已启用" : "已禁用");//备注}logger.info("方法createCorpDataExcel(List<CorpDirectorys> corpDirectoryList)构建Excel对象结束");return workbook;
}

##dubbo接口的service层#

  ① //是否存在子分类ServiceResult<Boolean> hasExistChild(Long id, Long companyId);②//如果有子目录,查询下当前子目录路径,通过路径去查询采购品列表ServiceResult<CorpCatalogs> findByPK(Long id, Long companyId);③ //查询出需要导出采购品的数量ServiceResult<Integer>  getTotal(CorpDirectorysQueryDto corpDirectorysQueryDto);④//查询出需要导出采购品数据ServiceResult<List<CorpDirectorys>> findByCondition(CorpDirectorysQueryDto corpDirectorysQueryDto, PageSet pageSet);

##dubbo接口的serviceImpl层#

 ① //是否存在子分类@Overridepublic ServiceResult<Boolean> hasExistChild(Long id, Long companyId) {ServiceResult<Boolean> result = new ServiceResult<Boolean>();try{CorpCatalogs corpCatalogs = new CorpCatalogs();corpCatalogs.setParentId( id  );corpCatalogs.setCompanyId( companyId );Long page_count = corpCatalogDao.findPage_count(corpCatalogs);if ( page_count != null && page_count > 0 ){result.setResult( true );}else {result.setResult( false );}}catch(Exception e){log.error("调用{}方法 异常", "[hasExistChild]");log.error("方法使用参数:[id:{},companyId:{}]", id,companyId);log.error("异常信息:{}", e);result.setErrMessage("调用 hasExistChild 方法异常,异常信息:" + e.getMessage());}return result;}②//如果有子目录,查询下当前子目录路径,通过路径去查询采购品列表@Overridepublic ServiceResult<CorpCatalogs> findByPK(Long id, Long companyId){ServiceResult<CorpCatalogs> result = new ServiceResult<CorpCatalogs>();try{CorpCatalogs resultEntity = null;if ( id != null && companyId != null){resultEntity = corpCatalogDao.getById(id, companyId);}result.setResult(resultEntity);}catch(Exception e){log.error("调用{}根据ID查询对应的条目时发生未知异常异常{},", "[findByPK]", e.getMessage());log.error("[id, companyId]{}", id + ";" + companyId);log.error("堆栈异常信息:{}", e);result.setErrMessage("根据ID查询对应的条目时发生未知异常!");}return result;}③ //查询出需要导出采购品的数量@Overridepublic ServiceResult<Integer> getTotal(CorpDirectorysQueryDto corpDirectorysQueryDto) {ServiceResult<Integer> result = new ServiceResult<>();try{Integer planListCount = corpDirectorysDao.getTotal(corpDirectorysQueryDto);result.setResult(planListCount);}catch(Exception e){log.error("调用{}方法 异常", "[DubboPlanServiceImpl.getMyPlanListCount]");log.error("方法使用参数:");log.error("异常信息:{}", e);result.setErrMessage("调用getMyPlanListCount方法异常,异常信息:" + e.getMessage());}return result;}④//查询出需要导出采购品数据@Overridepublic ServiceResult<List<CorpDirectorys>> findByCondition(CorpDirectorysQueryDto corpDirectorysQueryDto, PageSet pageSet) {ServiceResult<List<CorpDirectorys>> serviceResult = new ServiceResult<>();if ( corpDirectorysQueryDto == null ){log.error("corpDirectorysQueryDto is null");serviceResult.setErrMessage("参数不能为空");return serviceResult;}try {//第几页int pageNum = 0 ;//每页显示记录数int pageSize = Integer.MAX_VALUE;//设值if ( pageSet != null && pageSet.getPageNum() != null){pageNum = pageSet.getPageNum();}if ( pageSet != null && pageSet.getPageSize() != null ){pageSize = pageSet.getPageSize();}//分页Page<List<CorpDirectorys>> queryResult = PageHelper.startPage( pageNum , pageSize );if(pageSet != null){if(StringUtils.hasLength(pageSet.getSortColumn())) {PageHelper.orderBy(pageSet.getSortColumn());}}//查询serviceResult.setResult( getCorpDirectorysDao().findByCondition(corpDirectorysQueryDto) );serviceResult.setTotal( queryResult.getTotal() );}catch (Exception e){log.error("调用{}方法 异常", "DubboCorpDirectorysServiceImpl#findByCompanyId",e);log.error("方法使用参数:[companyId:{}]", corpDirectorysQueryDto);serviceResult.setErrMessage("调用findByCompanyId方法异常,异常信息:" + e.getMessage());}return serviceResult;}

##dubbo接口的dao层#

① //是否存在子分类Long findPage_count(CorpCatalogs corpCatalogs);
②//如果有子目录,查询下当前子目录路径CorpCatalogs getById(@Param("id") Long id, @Param("companyId") Long companyId);
③ //查询出需要导出采购品的数量Integer getTotal(CorpDirectorysQueryDto condition);
④//查询出需要导出采购品数据List<CorpDirectorys> findByCondition(CorpDirectorysQueryDto condition);

##dubbo接口的sql#

   ① //是否存在子分类<select id="findPage_count" resultType="long">SELECT count(1) FROM corp_catalog<include refid="findPage_where"/></select>
②//如果有子目录,查询下当前子目录路径<select id="getById" resultMap="RM_CorpCatalogs">SELECT<include refid="t_columns"/>FROM corp_catalogWHEREID = #{id} and company_id = #{companyId}</select>③同①sql一样,但条件不一样。④//查询出需要导出采购品数据<select id="findByCondition" resultMap="BaseResultMap">select<include refid="Base_Column_List"/>from `corp_directory`<include refid="findPage_where"/>ORDER BY CREATE_TIME DESC</select>

##Entity类以及DTO封装类(采购品)#(get,set函数省略)

public class CorpDirectorys extends CorpDirectorysKey implements Serializable {private static final long serialVersionUID = -659270055955419540L;/*** 名称*/@NotNull(message = "采购品名称不能为空!")@Length(min = 1, max = 200, message = "采购品名称长度在 {min}与{max}之间 !")private String name;/*** 规格/型号*/@Length(min = 0, max = 256, message = "规格型号 {min}与{max}之间 !")private String spec;/*** 货号*/@Length(min = 0, max = 768, message = "货号长度在 {min}与{max}之间 !")private String pcode;/*** 制造商*/@Length(min = 0, max = 768, message = "制造商长度在 {min}与{max}之间 !")private String productor;/*** 计量单位*/@NotNull(message = "计量单位不能为空!")@Length(min = 1, max = 10, message = "计量单位描述长度在 {min}与{max}之间 !")private String unitName;/*** 产地*/@Length(min = 0, max = 768, message = "产地长度在 {min}与{max}之间 !")private String producingAddress;/*** 用途*/@Length(min = 0, max = 768, message = "用途长度在 {min}与{max}之间 !")private String purpose;/*** 市场参考价格*/@Length(min = 0, max = 768, message = "市场参考价长度在 {min}与{max}之间 !")private String marketPrice;/*** 备注*/@Length(min = 0, max = 500, message = "备注长度在 {min}与{max}之间 !")private String demo;/*** 状态:1:启用,2:禁用* @see CorpDirectorysAbandonEnum*/@Range( min =  1 , max = 2 , message = "大小不合法")private Long abandon;/*** 品牌*/@Length(min = 0, max = 768, message = "品牌长度在 {min}与{max}之间 !")private String brand;/*** 产品特性*/@Length(min = 0, max = 768, message = "产品特性长度在 {min}与{max}之间 !")private String speciality;/*** 技术参数/材质*/@Length(min = 0, max = 500, message = "技术参数长度在 {min}与{max}之间 !")private String techParameters;/*** 所在分类ID*/private Long catalogId;/*** 来源* @see cn.bidlink.procurement.materials.dal.server.enums.CorpDirectorysSourceEnum*/private Integer source;/*** 所在分类名称,包含直接和间接分类名称,以/分隔,如/采购目录/汽车* 如果分类为空,则此字段为空*/private String catalogName;/*** 分类路径,包含直接和间接上级分类ID,以#分隔,如#1#563437187#* 如果分类为空,则此字段为空*/private String treePath;/*** 编码,唯一*/private String code;private Integer unitPrecision;private Integer pricePrecision;private String imgCode;private Date createTime;private Long createUserId;private String createUserName;private Date updateTime;private Long updateUserId;private String updateUserName;public class CorpDirectorysQueryDto implements Serializable{/** 企业ID,必填*/private Long companyId;/** 编码*/private String code;/** 编码(模糊匹配)*/private String codeLike;/** 名称 */private String name;/** 名称 (模糊匹配)*/private String nameLike;/** 规格/型号*/private String spec;/** 规格/型号(模糊匹配)*/private String specLike;/** 制造商*/private String productor;/** 制造商(模糊匹配)*/private String productorLike;/** 计量单位 */private String unitName;/** 计量单位 (模糊匹配)*/private String unitNameLike;/** 技术参数/材质*/private String techParameters;/** 技术参数/材质(模糊匹配)*/private String techParametersLike;/**启用禁用**/private Long abandon;/***采购品目录路径模糊匹配***/private String treepathLike;private  Long orgId;private String  treePath;private List<Long> catalogIdList;public String getTreePath() {return treePath;}public void setTreePath(String treePath) {this.treePath = treePath;}public String getTreepathLike() {return treepathLike;}public void setTreepathLike(String treepathLike) {this.treepathLike = treepathLike;}public Long getAbandon() {return abandon;}public void setAbandon(Long abandon) {this.abandon = abandon;}/*** 分类ID*/private Long catalogId;public class CorpDirectorysKey implements Serializable {/*** 主键*/private Long id;/*** 所属企业ID*/@NotNull(message = "所属企业ID不能为空!")private Long companyId;private static final long serialVersionUID = 1L;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public Long getCompanyId() {return companyId;}public void setCompanyId(Long companyId) {this.companyId = companyId;}

使用HSSFWorkbook并简单对数据分批查询完成导出excel功能(java实现)相关推荐

  1. SpringBoot后端+Vue之AntDesignVue前端实现查询表格导出excel功能

    用的是阿里的com.alibaba.excel包,pom的依赖如下 <dependency><groupId>com.alibaba</groupId><ar ...

  2. 大数据分页查询 or 导出 慢sql治理

    大数据分页查询 or 导出 慢sql治理 背景 缺陷 要求 优化方案 适用场景 方案优点 方案缺点 时间拆分如处理分页查询问题 方案说明 使用说明 分页查询工具 时间拆分工具 背景 当前日增数据量将近 ...

  3. springboot整合poi读取数据库数据和图片动态导出excel

    springboot整合poi读取数据库数据和图片动态导出excel 第一次操作 话不多说就直接上代码 实现代码 需要的依赖 <dependency><groupId>org. ...

  4. 导出Excel功能-从服务端到浏览器的简单处理

    导出Excel功能 从服务端到浏览器的简单处理, 仅供参考 服务端定义一个导出功能的关键代码 Java 定义一个export的功能函数,以下为关键代码(接口中的一部分处理逻辑): @Override ...

  5. java excel data 导入数据_java实现导入导出excel数据

    项目需要,要实现一个导入导出excel的功能,于是,任务驱动着我学习到了POI和JXL这2个java操作Excel的插件. 一.POI和JXL介绍 1.POI:是对所有office资源进行读写的一套工 ...

  6. poi导出数据文件名错误_POI导出Excel报错“扩展名与文件的格式不匹配”

    下面是我用POI导出Excel的实例: 依赖的jar包 org.apache.poi poi 4.0.1 工具类 public class ExportExcel { // 显示的导出表的标题 pri ...

  7. vue表单中批量导入功能_vue实战(11)——vue+element UI实现表格数据导出Excel功能

    一.应用场景 按照需求导出功能分为勾选批量导出及按照查询结果导出,考虑到接口操作导出的复杂性,因此实现了js控制导出的功能 导出功能截图 二.安装相关依赖 cnpm install --save xl ...

  8. java 列表数据List通过模板导出excel表和word表

    1.maven需要的jar包 <!-- exl导出 --> <dependency><groupId>net.sf.jxls</groupId>< ...

  9. ThingsBoard CE添加数据导出excel功能

    此文具体代码在文末语雀链接,需额外付费 b站效果演示地址 https://www.bilibili.com/video/BV1dK4y1P7hX 目录 前言 CE版本实现演示 组件设置页面修改 添加「 ...

最新文章

  1. 面试被问烂的 Spring IOC(求求你别再问了)
  2. Oracle数据库备份与恢复1\Oracle数据库备份与恢复(1)exp和imp 之三
  3. mysql隔离级别底层实现_1、深入理解mysql四种隔离级别及底层实现原理(MVCC和锁)...
  4. BZOJ1503(Splay)
  5. mvc crud_Spring MVC3 Hibernate CRUD示例应用程序
  6. vba上传文件到ftp服务器指定目录下面
  7. 转: c#.net利用RNGCryptoServiceProvider产生任意范围强随机数的办法
  8. python 阿里云短信接口_阿里云短信接口怎么使用
  9. lua定义一个简单的类
  10. CCNA 网络安全答案汇总
  11. object、param标签及页面显示PDF文件的方法
  12. 龙之谷冰龙linux手工服务端,【网游】【龙之谷】v300冰龙巢穴一键服务端+客户端+GM工具+视频教程...
  13. UE4 半透明材质粒子无法在透明背景前显示问题
  14. 苹果NFC功能以及Apple Pay的初探
  15. python实现分层随机抽样算法_python分层随机抽样
  16. 开心网刷分程序详解以及web游戏破解思路分析(一)
  17. 一世人中,最黑仔嘅一日
  18. 58私信怎么引流?58同城如何引流到微信?怎么用58同城做引流
  19. Python实例--遍历文件夹下所有的文件或文件夹
  20. Spring-Boot启动方式,以及线上部署

热门文章

  1. HD钱包生成源码解读
  2. A Survey of Compiler Testing
  3. 小学数学与计算机整合课优质教案,小学数学与信息技术整合教案
  4. typora 有道云笔记_有道云笔记 for Mac(笔记软件)中文免费版
  5. java jackson漏洞_CVE-2019-12086 jackson任意文件读取漏洞
  6. 设置echarts随页面大小变化自适应
  7. Nginx入门到精通1-nginx基础及环境搭建
  8. windows10系统下PS、AI等软件界面字很小如何解决
  9. OSTeC: One-Shot Texture Completion
  10. cv练习:看图说话(Image Captioning)--1