青岛做物流网站,南昌汉邦网站建设,网站专题怎么做呢,网站的色彩搭配文章目录 前言正文一、项目依赖二、封装表格实体和Sheet实体2.1 表格实体2.2 Sheet实体 三、核心实现3.1 核心实现之导出为输出流3.2 web导出3.3 导出为字节数组 四、调试4.1 构建调试用的实体类4.2 控制器调用4.3 测试结果 五、注册大数转换器#xff0c;长度大于15时#x… 文章目录 前言正文一、项目依赖二、封装表格实体和Sheet实体2.1 表格实体2.2 Sheet实体 三、核心实现3.1 核心实现之导出为输出流3.2 web导出3.3 导出为字节数组 四、调试4.1 构建调试用的实体类4.2 控制器调用4.3 测试结果 五、注册大数转换器长度大于15时转换为字符串5.1 实现转换器5.2 使用转换器 前言
工作中遇到一个需求一次导出多个Excel 文件并且每个excel中可能存在1到多个sheet页。 好在没有那种单元格合并的要求。
总体的思路是设计两个实体一个表示表格一个表示sheet 数据。并且表格包含一个list 类型的sheet对象。
然后再使用ZipOutputStream、ExcelWriterBuilder、EasyExcel#writerSheet(...) 等类和方法去组装表格最终进行压缩。
项目整体使用 java 8 和 阿里的easyexcel工具包。
正文
一、项目依赖
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdversion2.2.0.RELEASE/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.2/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIdeasyexcel/artifactIdversion2.2.11/versionexclusionsexclusiongroupIdorg.slf4j/groupIdartifactIdslf4j-api/artifactId/exclusion/exclusions/dependency/dependencies二、封装表格实体和Sheet实体
2.1 表格实体
/*** excel数据*/
Data
public static class ExcelData {// sheet的列表private final ListExcelShellData? shellDataList new ArrayList();// 表格文件名private String filename;public void addShellData(ExcelShellData? excelShellData) {this.shellDataList.add(excelShellData);}
}2.2 Sheet实体
/*** sheet数据*/
Data
AllArgsConstructor
public static class ExcelShellDataT {// 数据private ListT list;// sheet名private String sheetName;// 数据实体类型private ClassT clazz;
}三、核心实现
3.1 核心实现之导出为输出流
这一步主要组装表格数据以及生成sheet。最终将数据放到输出流outputStream中 。
private static void exportZipStream(ListExcelData excelDataList, OutputStream outputStream) {try {// 开始存入try (ZipOutputStream zipOut new ZipOutputStream(outputStream)) {try {for (ExcelData excelData : excelDataList) {ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream();com.alibaba.excel.ExcelWriter excelWriter null;try {ExcelWriterBuilder builder EasyExcel.write(byteArrayOutputStream).autoCloseStream(false)// 自动适配.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy());excelWriter builder.build();zipOut.putNextEntry(new ZipEntry(excelData.getFilename()));// 开始写入excelfor (ExcelShellData? shellData : excelData.getShellDataList()) {WriteSheet writeSheet EasyExcel.writerSheet(shellData.getSheetName()).head(shellData.getClazz()).build();excelWriter.write(shellData.getList(), writeSheet);}} catch (Exception e) {throw new RuntimeException(导出Excel异常, e);} finally {if (excelWriter ! null) {excelWriter.finish();}}byteArrayOutputStream.writeTo(zipOut);zipOut.closeEntry();}} catch (Exception e) {throw new RuntimeException(导出Excel异常, e);}}} catch (IOException e) {throw new RuntimeException(导出Excel异常, e);}}3.2 web导出
可以调用本方法直接在Controller中调用之后当访问对应url会直接下载到浏览器。 /*** 导出多个sheet到多个excel文件并压缩到一个zip文件*/public static void exportZip(String zipFilename, ListExcelData excelDataList, HttpServletResponse response) {try {// 这里URLEncoder.encode可以防止中文乱码zipFilename URLEncoder.encode(zipFilename, utf-8);// 指定文件名response.setHeader(Content-disposition, attachment;filename zipFilename);response.setContentType(application/x-msdownload);response.setCharacterEncoding(utf-8);exportZipStream(excelDataList, response.getOutputStream());} catch (IOException e) {throw new RuntimeException(导出Excel异常, e);}}3.3 导出为字节数组
当我们需要导出为字节数组时可以调用本方法。之后随你怎么加工。 /*** 导出多个sheet到多个excel文件并压缩到一个zip文件。最终得到一个字节数组。*/public static byte[] exportZip(ListExcelData excelDataList) {ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream();exportZipStream(excelDataList, byteArrayOutputStream);return byteArrayOutputStream.toByteArray();}四、调试
4.1 构建调试用的实体类
指定简单的几个字段作为导出数据。 DataAllArgsConstructorpublic static class DemoData {ExcelProperty(字符串标题)private String string;ExcelProperty(日期标题)private Date date;ExcelProperty(数字标题)private Double doubleData;}4.2 控制器调用
组装假数据进行导出。
Controller
RequestMapping(/excel)
public class ExcelDemoController {GetMapping(/exportTransportDetail)public String exportTransportDetail(HttpServletResponse response) throws IOException {// 压缩包文件名String fileName 结算单运单明细- System.currentTimeMillis() .zip;ListExcelData excelDataList new ArrayList();// 第一个ExcelExcelData excelData1 new ExcelData();excelData1.setFilename(结算单运单明细-1- System.currentTimeMillis() .xlsx);ListDemoData demoData1 new ArrayList();demoData1.add(new DemoData(excel-sheet1, new Date(), 123112.321));demoData1.add(new DemoData(excel-sheet1, new Date(), 34.3));ListDemoData demoData2 new ArrayList();demoData2.add(new DemoData(excel-sheet2, new Date(), 123112.321));demoData2.add(new DemoData(excel-sheet2, new Date(), 34.3));ExcelShellDataDemoData shellData1 new ExcelShellData(demoData1, sheet1, DemoData.class);ExcelShellDataDemoData shellData2 new ExcelShellData(demoData2, sheet2, DemoData.class);excelData1.addShellData(shellData1);excelData1.addShellData(shellData2);// 第2个ExcelExcelData excelData2 new ExcelData();excelData2.setFilename(结算单运单明细-2- System.currentTimeMillis() .xlsx);ListDemoData demoData21 new ArrayList();demoData21.add(new DemoData(excel-sheet21, new Date(), 123112.321));demoData21.add(new DemoData(excel-sheet22, new Date(), 34.3));ListDemoData demoData22 new ArrayList();demoData22.add(new DemoData(excel-sheet21, new Date(), 123112.321));demoData22.add(new DemoData(excel-sheet22, new Date(), 34.3));ExcelShellDataDemoData shellData21 new ExcelShellData(demoData21, sheet1, DemoData.class);ExcelShellDataDemoData shellData22 new ExcelShellData(demoData22, sheet2, DemoData.class);excelData2.addShellData(shellData21);excelData2.addShellData(shellData22);excelDataList.add(excelData1);excelDataList.add(excelData2);// 写法1///// exportZip(fileName, excelDataList , response);// 写法2///byte[] bytes exportZip(excelDataList);response.setHeader(Content-disposition, attachment;filename fileName);response.setContentType(application/x-msdownload);response.setCharacterEncoding(utf-8);response.getOutputStream().write(bytes);response.getOutputStream().flush();return succ;}
}4.3 测试结果
可以看到压缩包解压后的效果 其中一个文件内容如下 sheet1
sheet2
五、注册大数转换器长度大于15时转换为字符串
5.1 实现转换器
/*** Excel 数值长度大于maxLength的数值转换为字符串*/public static class ExcelBigNumberConvert implements ConverterLong {private final int maxLength;public ExcelBigNumberConvert() {this(15);}public ExcelBigNumberConvert(Integer maxLength) {this.maxLength maxLength;}Overridepublic ClassLong supportJavaTypeKey() {return Long.class;}Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}Overridepublic Long convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {Object data cellData.getData();if (data null) {return null;}String s String.valueOf(data);if (s.matches(^\\d$)) {return Long.parseLong(s);}return null;}Overridepublic CellDataObject convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {if (object ! null) {String str object.toString();if (str.length() maxLength) {return new CellData(str);}}return null;}}5.2 使用转换器
在构建建造器时增加注册转换器即可。