org.apache.poi3.1.7 Excle并发批量导入导出
org.apache.poi3.1.7 升级,需要修改设置方式:
1、org.apache.poi3.1.4 的设置单元格:
XSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 居中
cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);//垂直
org.apache.poi3.1.7的设置单元格,格式为:
XSSFCellStyle cellStyle = wb.createCellStyle();
cellStylestyle.setAlignment(HorizontalAlignment.CENTER);// 居中
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);;//垂直
2、同时在设置边框时候,也有相应的同样问题,HSSFCellStyle 中同样报错没有其中的值
cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
需要升级一下方式:
cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
cellStyle.setBorderTop(BorderStyle.THIN);//上边框
cellStyle.setBorderRight(BorderStyle.THIN);//右边框
3、代码分享:EXCLE导入导出,二话不说直接上代码:
import com.fasterxml.jackson.annotation.JsonIgnore; import com.ppdai.wechat.contract.model.CoverBuildingInfo; import com.ppdai.wechat.contract.request.BatchInsertBuildingRequest; import com.ppdai.wechat.spring.entity.OutputResult; import com.ppdai.wechat.spring.service.CoverBuildingMService; import com.ppdai.wechat.spring.util.CommonUtil; import com.ppdai.wechat.spring.util.StringUtil; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.beans.PropertyDescriptor; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.util.*; import java.util.concurrent.*; /** * Description:Excel解析 * Created by xiaoyongyong on 2017/11/15. * Version: 1.0 */ @Service public class AwardExcelReader { @Autowired private CoverBuildingMService coverBuildingMService; private Logger logger = LoggerFactory.getLogger(AwardExcelReader.class); private static CountDownLatch latch = new CountDownLatch(10); private static ExecutorService executorService = Executors.newFixedThreadPool(5); private int pageIndex = 0; /** * Excel的导出数据和格式设定 * Excel 2003及以下的版本。一张表最大支持65536行数据,256列。也就是说excel2003完全不可能满足百万数据导出的需求。 * Excel 2007-2010版本。一张表最大支持1048576行,16384列; * * @param data title对应的属性 * @param titles 导出Excle的列头 * @param list 查询的list集合 * @param response HttpServletResponse * @param fileName 文件名 * @throws Exception Exception */ public static <T> void excelData(String[] data, String[] titles, List<T> list, HttpServletResponse response, String fileName) throws Exception { // 生成提示信息, response.setContentType("application/vnd.ms-excel"); try (OutputStream os = response.getOutputStream()) { // 进行转码,使其支持中文件名 String codeFileName = java.net.URLEncoder.encode(fileName, "UTF-8"); response.setHeader("content-disposition", "attachment;filename=" + codeFileName + ".xlsx"); // 生成工作簿对象 SXSSFWorkbook workbook = new SXSSFWorkbook(); //产生工作表对象 SXSSFSheet sheet = workbook.createSheet(); //循环表头 for (int i = 0; i < titles.length; i++) { //设置表列宽 sheet.setColumnWidth((short) i, 25 * 256); } //设置统一单元格的高度 sheet.setDefaultRowHeight((short) 300); //样式1 CellStyle style = workbook.createCellStyle(); // 样式对象 style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直 style.setAlignment(HorizontalAlignment.CENTER); // 水平 style.setWrapText(true); //设置是否能够换行,能够换行为true style.setBorderBottom(BorderStyle.THIN); //设置下划线,参数是黑线的宽度 style.setBorderLeft(BorderStyle.THIN); //设置左边框 style.setBorderRight(BorderStyle.THIN); //设置有边框 style.setBorderTop(BorderStyle.THIN); //设置上边框 //设置标题字体格式 Font font = workbook.createFont(); //设置字体样式 font.setFontHeightInPoints((short) 20); //设置字体大小 font.setFontName("Courier New"); //设置字体,例如:宋体 List<Field> fieldList = new ArrayList<>(); //支持子类父类两级 fieldList.addAll(Arrays.asList(list.get(0).getClass().getDeclaredFields())); fieldList.addAll(Arrays.asList(list.get(0).getClass().getSuperclass().getDeclaredFields())); Map<String, Field> fieldMap = new HashMap<>(); for (Field field : fieldList) { if ("serialVersionUID".equals(field.getName())) continue; field.setAccessible(true); fieldMap.put(field.getName(), field); } //创建第一行 SXSSFRow row = sheet.createRow(0); //为第一行的所有列赋值 for (int i = 0; i < titles.length; i++) { SXSSFCell cell = row.createCell(i); cell.setCellValue(titles[i]); } //循环list集合,把数据写到Excel if (!list.isEmpty()) { int i = 1; for (T tt : list) { // 创建除第一行的一下data行 SXSSFRow sxssfRow = sheet.createRow(i++); String val = ""; // 创建一行的所有列并为其赋值 for (int v = 0; v < data.length; v++) { Field field = fieldMap.get(data[v]); if (!field.isAnnotationPresent(JsonIgnore.class)) { Object fieldValue = new PropertyDescriptor(field.getName(), tt.getClass()).getReadMethod().invoke(tt); if (fieldValue == null) { val = ""; } else { val = fieldValue.toString(); } } sxssfRow.createCell(v).setCellValue(val); } } } workbook.write(os); } catch (IOException e) { e.printStackTrace(); } } /** * 批量读取Excle * @param uploadFile 上传的Excle文件 * @param pageSize 多线程解析excle的行数 * @throws Exception */ public void importExcel(MultipartFile uploadFile, Integer pageSize) throws Exception { //解析excel 2007 版本文件 String awardName = uploadFile.getOriginalFilename().substring(0, uploadFile.getOriginalFilename().indexOf(".")); XSSFWorkbook workbook = new XSSFWorkbook(uploadFile.getInputStream());// XSSFSheet sheet = workbook.getSheetAt(0); int totalRows = sheet.getLastRowNum() + 1;//一共有多少行 if (totalRows == 0) { throw new Exception("请填写数据!"); } try { List<Future> futures = new ArrayList<>(); for (int i = 0; i < 10; i++) { futures.add(executorService.submit(new AwardExcelReader.ReaderImport(pageSize, totalRows, sheet, awardName))); } for (Future future : futures) { if (future.get() != null) { latch.countDown(); } } latch.await();//命令发送后指挥官处于等待状态,一旦cdAnswer为0时停止等待继续往下执行 } catch (Exception e) { pageIndex = 0; logger.error("importExcel处理异常,异常信息", e); } finally { pageIndex = 0; System.gc(); } } private class ReaderImport implements Callable<Object> { private Integer pageSize; private Integer totalRows; private XSSFSheet sheet; private String awardName; ReaderImport(Integer pageSize, Integer totalRows, XSSFSheet sheet, String awardName) { this.pageSize = pageSize; this.totalRows = totalRows; this.sheet = sheet; this.awardName = awardName; } @Override public Object call() throws Exception { start(pageSize, totalRows, sheet, awardName); return 1; } } private void start(Integer pageSize, Integer totalRows, XSSFSheet sheet, String awardName) throws Exception { while (true) { //1、批量读取Excel数据,分批次查询,一次查询1000条 BatchInsertBuildingRequest request = new BatchInsertBuildingRequest(); synchronized (this) { pageIndex++; List<CoverBuildingInfo> coverBuildingInfos = new ArrayList<>(); for (int rowIndex = pageIndex * pageSize - pageSize == 0 ? 0 : pageIndex * pageSize - pageSize + 1; rowIndex <= pageIndex * pageSize; rowIndex++) { XSSFRow row = sheet.getRow(rowIndex); if (row == null) { continue; } if (StringUtil.isNullOrEmpty(CommonUtil.getCellValue(row.getCell(0)))) { continue; } CoverBuildingInfo coverBuildingInfo = new CoverBuildingInfo(); coverBuildingInfo.setAwardName(awardName); coverBuildingInfo.setAward(CommonUtil.getCellValue(row.getCell(0))); coverBuildingInfo.setRemark(String.valueOf(pageIndex)); coverBuildingInfos.add(coverBuildingInfo); } request.setCoverBuildingInfos(coverBuildingInfos); if (pageIndex > CommonUtil.getTotalPage(pageSize, totalRows)) { break; } } OutputResult baseResponse = coverBuildingMService.batchInsertBuilding(request); if (baseResponse.getResult() != 0) { logger.error("批量写入数据异常,异常信息", baseResponse.getResultMessage()); } } } }
public class CommonUtil { public static Integer getTotalPage(Integer pageSize, Integer totalCount) { Integer totalPage; if (totalCount % pageSize == 0) { totalPage = totalCount / pageSize; } else { totalPage = totalCount / pageSize + 1; } return totalPage; } /** * 获取Cell内容 * @param cell cell * @return String */ public static String getCellValue(Cell cell) { String cellValue = ""; if (cell != null) { switch (cell.getCellTypeEnum()) { case STRING: cellValue = cell.getStringCellValue(); break; case NUMERIC: cellValue = cell.getNumericCellValue() + ""; break; case BLANK: break; default: break; } } return cellValue; } }
下面是实用类:
@RequestMapping("/export") public void export(HttpServletResponse response, @RequestParam(required = false) Integer activityId) throws Exception { long s1 = System.currentTimeMillis(); String[] titles = new String[]{"奖励名称", "奖励", "是否赠送", "修改时间"}; String[] data = new String[]{"awardName", "award", "useful", "updatetime"}; List<CoverBuildingBO> list = new ArrayList<>(); long start = System.currentTimeMillis(); reader.excelData(data, titles, list, response, fileName); long spend = System.currentTimeMillis() - start; long s2 = System.currentTimeMillis() - s1; System.out.println("文件总数:" + list.size() + "条,excel生成耗时:" + spend + "毫秒" + ",总耗时:" + s2 + "毫秒."); }