福建厦门网站建设,电气营销型网站方案,有限公司企业网站建设方案,上海网络推广营销1、背景介绍
项目中需要导出数据质检结果#xff0c;本来使用Excel#xff0c;但是质检结果数据行数过多#xff0c;导致用hutool报错#xff0c;因此转为导出csv格式数据。
2、参考文档
https://blog.csdn.net/ityqing/article/details/127879556 工程环境#xff1a;…1、背景介绍
项目中需要导出数据质检结果本来使用Excel但是质检结果数据行数过多导致用hutool报错因此转为导出csv格式数据。
2、参考文档
https://blog.csdn.net/ityqing/article/details/127879556 工程环境springboot 2.2.x
3、实现
controller ApiOperation(导出质检结果csv)GetMapping(/export/csv/{datasetId})public void exportCsv( PathVariable String datasetId,HttpServletResponse response) {CheckDataParamVO checkDataParamVO new CheckDataParamVO();checkDataParamVO.setDatasetId(datasetId);checkDataService.exportCsv(checkDataParamVO, response);}service /*** 导出csv格式质检结果** param checkDataVO* param response*/Overridepublic void exportCsv(CheckDataParamVO checkDataVO, HttpServletResponse response) {ListCheckResultVO res getCheckResultAll(checkDataVO);String fileName 质检结果表 DateTime.now().getTime();writeCsv(response, fileName, res);}/*** CSV文件列分隔符*/private static final String CSV_COLUMN_SEPARATOR ,;/*** CSV文件行分隔符*/private static final String CSV_ROW_SEPARATOR System.lineSeparator();private static final ListString titleName Arrays.asList(序号, 异常类型, 图层名, 要素主键);/*** param response 响应流* param fileName 文件名称* param dataList 数据源*/private void writeCsv(HttpServletResponse response, String fileName, ListCheckResultVO dataList) {OutputStream out null;try {StringBuffer buf new StringBuffer();out response.getOutputStream();String lastFileName fileName .csv;response.setContentType(application/msexcel;charsetUTF-8);response.setHeader(Content-Disposition, attachment; filename URLEncoder.encode(lastFileName, UTF-8));// 组装表头for (String title : titleName) {buf.append(title).append(CSV_COLUMN_SEPARATOR);}buf.append(CSV_ROW_SEPARATOR);//组装行数据dataList.forEach(data - {buf.append(Optional.ofNullable(data.getSid()).orElse(0)).append(CSV_COLUMN_SEPARATOR);buf.append(Optional.ofNullable(data.getCheckType()).orElse()).append(CSV_COLUMN_SEPARATOR);buf.append(Optional.ofNullable(data.getSubname()).orElse()).append(CSV_COLUMN_SEPARATOR);buf.append(Optional.ofNullable(data.getFid()).orElse()).append(CSV_COLUMN_SEPARATOR);buf.append(CSV_ROW_SEPARATOR);});//添加bom不加Excel打开中文会乱码out.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});out.write(buf.toString().getBytes(UTF-8));} catch (Exception e) {log.error(导出CSV异常, e);} finally {if (out ! null) {try {out.flush();out.close();} catch (IOException e) {log.error(导出CSV异常, e);}}}}4、测试结果
可用
5、总结
以上是不使用第三方组件实现导出csv文件。测试成功。
6、补充
参考文章 https://blog.csdn.net/ityqing/article/details/127879556
6.1、bug
提到了一个中文乱码的bug Excel 在读取 csv 的时候是通过读取文件头上的 bom 来识别编码的这导致如果我们生成 csv 文件的平台输出无 bom 头编码的 csv 文件例如 utf-8 在标准中默认是可以没有 bom 头的Excel 只能自动按照默认编码读取不一致就会出现乱码问题了。
6.2、解决
写入的时候加上 out.write(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF });
6.3、其他方式
参考文章用了两种方法另一种是引入第三方组件CSVWriter pom.xml文件增加依赖
dependencygroupIdcom.opencsv/groupIdartifactIdopencsv/artifactIdversion5.5.2/version
/dependencyjava代码如下自己没测。只是抄过来
/**
* param response 响应流
* param fileName 文件名称
* param dataList 数据源
*/
private void writeCsv2(HttpServletResponse response, String fileName, ListTaskAplusExpire dataList) {String lastFileName fileName .csv;response.setContentType(application/msexcel;charsetUTF-8);try {response.setHeader(Content-Disposition, attachment; filename URLEncoder.encode(lastFileName, UTF-8));PrintWriter out response.getWriter();// 手动加上BOM标识out.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }));// 设置显示的顺序,数据源对象属性列表String[] columnMapping { pmid, phone, sendDate, code, message };ColumnPositionMappingStrategyTaskAplusExpire mapper new ColumnPositionMappingStrategyTaskAplusExpire();//数据源类型mapper.setType(TaskAplusExpire.class);mapper.setColumnMapping(columnMapping);// 写表头CSVWriter csvWriter new CSVWriter(response.getWriter(), CSVWriter.DEFAULT_SEPARATOR,CSVWriter.NO_QUOTE_CHARACTER);String[] header { Pmid,Phone,Send Date,Code,Message};csvWriter.writeNext(header);StatefulBeanToCsv beanToCsv new StatefulBeanToCsvBuilder(out).withMappingStrategy(mapper).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER).withSeparator(CSVWriter.DEFAULT_SEPARATOR).withEscapechar(\\).build();beanToCsv.write(dataList);csvWriter.close();out.close();} catch (IOException e) {e.printStackTrace();}catch (CsvDataTypeMismatchException e) {e.printStackTrace();} catch (CsvRequiredFieldEmptyException e) {e.printStackTrace();}