当前位置: 首页 > news >正文

邵阳红网站wordpress详细指南

邵阳红网站,wordpress详细指南,湛江网站建设优化建站,科技论文发表网一、背景 有一次项目的需求要求导出excel,并且将不同的数据分别写到不同的sheet中。 二、 方案概述 首先一开始使用easyexcel去导出excel,结果发现导出时间需要3秒左右。于是想着能不能缩短excel导出时间,于是第一次尝试使用异步线程去查询数…

一、背景

        有一次项目的需求要求导出excel,并且将不同的数据分别写到不同的sheet中。

二、 方案概述

        首先一开始使用easyexcel去导出excel,结果发现导出时间需要3秒左右。于是想着能不能缩短excel导出时间,于是第一次尝试使用异步线程去查询数据库,却发现接口的时间并没有明显缩短,于是自己就开始排查耗时的操作,于是发现是写sheet的时候是串行执行,并且每个写sheet的时间并不短,尤其在sheet比较多的时候,会导致导出的时间比较长。于是,想着能不能使用异步线程并发去写sheet,但是,使用的时候报错。后来去找报错的原因,是因为easyexcel并不支持并发写。于是,我就转战POI。尝试是否能够并发写入多个sheet。

使用easyexcel写入多个sheet

        try {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode(EXCEL, "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");AtomicInteger atomicInteger = new AtomicInteger(0);ExcelWriter build = EasyExcel.write(response.getOutputStream(),VirtualInstanceDataPoint.class).build();list.stream().map(i -> CompletableFuture.supplyAsync(() -> {return service.list();}, executor)).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList()).forEach(r->{int andIncrement = atomicInteger.getAndIncrement();WriteSheet build1 = EasyExcel.writerSheet(andIncrement, r.get(0).getDevice() + andIncrement).build();build.write(r, build1);});build.finish();response.flushBuffer();} catch (Exception e) {// 重置responseresponse.reset();response.setContentType("application/json");response.setCharacterEncoding("utf-8");response.getWriter().println(JSON.toJSONString(R.error().message(e.getMessage()).code(20007)));
}

并发写入多个sheet会报

org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException: A part with the name '/xl/worksheets/sheet1.xml' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]

 POI写入多个sheet

    String[] EXPORT_HEADER = {"head1","head2"};@GetMapping("export3")@ApiOperation(value = "excel导出信息")@SneakyThrowspublic void export3(HttpServletResponse response) {OutputStream outputStream = response.getOutputStream();response.reset();response.setContentType("application/vnd.ms-excel");response.setHeader("Content-disposition", "attachment;filename=template.xls");AtomicInteger atomicInteger = new AtomicInteger();HSSFWorkbook workbook = new HSSFWorkbook();Font font = workbook.createFont();font.setBold(true);HSSFCellStyle cellStyle = workbook.createCellStyle();cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);cellStyle.setFont(font);List<IndexData> indexDatas = new ArrayList<>();indexDatas.add(new IndexData("1",1.1));indexDatas.add(new IndexData("2",2.2));indexDatas.add(new IndexData("3",3.3));for (IndexData indexData : indexDatas) {HSSFSheet sheet = workbook.createSheet(indexData.getStr());HSSFRow row = sheet.createRow(0);// 创建表头for (int i = 0; i < EXPORT_HEADER.length; i++) {HSSFCell cell = row.createCell(i);cell.setCellValue(EXPORT_HEADER[i]);cell.setCellStyle(cellStyle);}row = sheet.createRow(1);row.createCell(0).setCellValue(indexData.getStr());row.createCell(1).setCellValue(indexData.getDoubleData());}workbook.write(outputStream);outputStream.flush();outputStream.close();}static  class IndexData {public IndexData(String string, Double doubleData) {this.str = string;this.doubleData = doubleData;}public String getStr() {return str;}public Double getDoubleData() {return doubleData;}private String str;private Double doubleData;}

POI多线程写多个sheet

    String[] EXPORT_HEADER = {"head1","head2"};@GetMapping("export3")@ApiOperation(value = "excel导出")@SneakyThrowspublic void export3(HttpServletResponse response) {OutputStream outputStream = response.getOutputStream();response.reset();response.setContentType("application/vnd.ms-excel");response.setHeader("Content-disposition", "attachment;filename=template.xls");AtomicInteger atomicInteger = new AtomicInteger();HSSFWorkbook workbook = new HSSFWorkbook();Font font = workbook.createFont();font.setBold(true);HSSFCellStyle cellStyle = workbook.createCellStyle();cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);cellStyle.setFont(font);List<IndexData> indexDatas = new ArrayList<>();indexDatas.add(new IndexData("1",1.1));indexDatas.add(new IndexData("2",2.2));indexDatas.add(new IndexData("3",3.3));indexDatas.stream().map(data ->CompletableFuture.runAsync(() ->{HSSFSheet sheet = workbook.createSheet(data.getStr());HSSFRow row = sheet.createRow(0);// 创建表头for (int i = 0; i < EXPORT_HEADER.length; i++) {HSSFCell cell = row.createCell(i);cell.setCellValue(EXPORT_HEADER[i]);cell.setCellStyle(cellStyle);}row = sheet.createRow(1);row.createCell(0).setCellValue(data.getStr());row.createCell(1).setCellValue(data.getDoubleData());})).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList());workbook.write(outputStream);outputStream.flush();outputStream.close();}static  class IndexData {public IndexData(String string, Double doubleData) {this.str = string;this.doubleData = doubleData;}public String getStr() {return str;}public Double getDoubleData() {return doubleData;}private String str;private Double doubleData;}

但是有时候会报错

java.lang.IllegalArgumentException: calculated end index (2576) is out of allowable range (2564..2569)

是因为在 子线程中创建sheet产生并发。

一个解决方案是主线程预先创建sheet

另一个方案是为创建sheet的操作加锁

    @GetMapping("export1")@ApiOperation(value = "excel导出信息")@SneakyThrowspublic void export2(HttpServletResponse response) {OutputStream outputStream = response.getOutputStream();response.reset();response.setContentType("application/vnd.ms-excel");response.setHeader("Content-disposition", "attachment;filename=template.xls");AtomicInteger atomicInteger = new AtomicInteger();HSSFWorkbook workbook = new HSSFWorkbook();Font font = workbook.createFont();font.setBold(true);HSSFCellStyle cellStyle = workbook.createCellStyle();cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);cellStyle.setFont(font);list.stream().map(instanceId -> CompletableFuture.runAsync(() -> {List<> collect =  service.list();HSSFSheet sheet = workbook.createSheet(collect.get(0).getDevice()+ atomicInteger.getAndIncrement());HSSFRow row = sheet.createRow(0);// 创建表头for (int i = 0; i < EXPORT_HEADER.length; i++) {HSSFCell cell = row.createCell(i);cell.setCellValue(EXPORT_HEADER[i]);cell.setCellStyle(cellStyle);}for (int i = 0; i < collect.size(); i++) {row = sheet.createRow(i + 1);row.createCell(0).setCellValue(collect.get(i).getInstanceId());row.createCell(1).setCellValue(collect.get(i).getDevice());row.createCell(2).setCellValue(collect.get(i).getDataId());row.createCell(3).setCellValue(collect.get(i).getDataName());}}, executor)).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList());workbook.write(outputStream);outputStream.flush();outputStream.close();}

以下使用加锁方式

    String[] EXPORT_HEADER = {"head1","head2"};@GetMapping("export3")@ApiOperation(value = "excel导出信息")@SneakyThrowspublic void export3(HttpServletResponse response) {OutputStream outputStream = response.getOutputStream();response.reset();response.setContentType("application/vnd.ms-excel");response.setHeader("Content-disposition", "attachment;filename=template.xls");AtomicInteger atomicInteger = new AtomicInteger();HSSFWorkbook workbook = new HSSFWorkbook();Font font = workbook.createFont();font.setBold(true);HSSFCellStyle cellStyle = workbook.createCellStyle();cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);cellStyle.setFont(font);List<IndexData> indexDatas = new ArrayList<>();indexDatas.add(new IndexData("1",1.1));indexDatas.add(new IndexData("2",2.2));indexDatas.add(new IndexData("3",3.3));indexDatas.stream().map(data ->CompletableFuture.runAsync(() ->{HSSFSheet sheet = getSheet(data, workbook);HSSFRow row = sheet.createRow(0);// 创建表头for (int i = 0; i < EXPORT_HEADER.length; i++) {HSSFCell cell = row.createCell(i);cell.setCellValue(EXPORT_HEADER[i]);cell.setCellStyle(cellStyle);}row = sheet.createRow(1);row.createCell(0).setCellValue(data.getStr());row.createCell(1).setCellValue(data.getDoubleData());})).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList());workbook.write(outputStream);outputStream.flush();outputStream.close();}@org.jetbrains.annotations.NotNullprivate synchronized static HSSFSheet getSheet(IndexData data, HSSFWorkbook workbook) {HSSFSheet sheet = workbook.createSheet(data.getStr());return sheet;}

但是这种方式还是会有一些并发带来的错误。

java.lang.NullPointerException: null
    at org.apache.poi.hssf.record.SSTSerializer.serialize(SSTSerializer.java:70)
    at org.apache.poi.hssf.record.SSTRecord.serialize(SSTRecord.java:279)
    at org.apache.poi.hssf.record.cont.ContinuableRecord.getRecordSize(ContinuableRecord.java:60)
    at org.apache.poi.hssf.model.InternalWorkbook.getSize(InternalWorkbook.java:1072)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.getBytes(HSSFWorkbook.java:1474)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.write(HSSFWorkbook.java:1386)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.write(HSSFWorkbook.java:1374)

但是在本机实测100个线程10个循环出错的个数在20-30之间

我们可以捕获这些错误使用do while循环,当出错的时候可以清空状态再次重试。

总结:

        该方法只是本菜鸡的愚见,使用这种方式的确可以完成并发写sheet,缩短接口的相应速度,将3秒左右的接口降低到50ms左右。应该能适合sheet略多,但并发量、数据量不多的excel导出,但本人也是第一次使用POI,所以可能有错误,希望大佬们能够多多指点。

http://www.yayakq.cn/news/470074/

相关文章:

  • 购物网站备案百度怎么优化网站关键词
  • 东钱湖镇建设局网站视频网站开发技术书
  • 常州云之家网站建设公司怎么样安卓手机优化大师官方下载
  • 眉山网站推广做网站 阿里云和百度云哪个好
  • 商城网站入驻系统最近军事新闻热点大事件
  • 网站开发一定找前端么营销互联网推广
  • 一个人做网站赚钱食品网站设计欣赏
  • 国外网站模板最好加盟网站建设
  • 网站增加关键词慈溪网站制作哪家最好
  • 微信公众号 链接微网站哪里有学平面设计的学校
  • 网站怎么销售女生做网站编辑好吗
  • 做微商哪个网站好H5响应式网站示例
  • 印刷做网站网上接单秦皇岛市第一医院
  • 做地方特产的网站杭州做网站的企业
  • dz网站建设器wordpress editor ios
  • 网站开发好学吗如何查看网站关键词
  • 怎么查看网站是否被收录专业数据分析网站
  • 网站开发学哪些公司介绍模板word
  • 做网站需要自备服务器吗正规设计兼职网站有哪些
  • 牡丹江营商环境建设监督局网站wordpress加印章插件
  • 宝山区建设用地事务所网站优化大师是什么软件
  • 塔城地区建设工程信息网站华为网站建设和阿里云哪个好
  • 东莞网站建设排名公司工业软件开发公司
  • 用python做网站和用php助孕网站优化推广
  • 网上开店网站做网站用到什么开发语言
  • 做网站打电话话术建设网站公司地址
  • html5 php 网站源码wordpress迁移到本地
  • 郑州大型网站建设价格西安电商网站开发
  • 网站推广排名网站访问量来源
  • 新网站建设的工作总结互联网保险发展现状和趋势