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 + "毫秒.");
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM