欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

POI 生成Excel

程序员文章站 2022-03-06 22:26:17
...

java 利用 poi 的 xssf 生成 excel
xssf :操作Excel2007以后的 .xlsx 文件
hssf :操作Exce2003之前的 .xls 文件
因为现在使用excel基本上是 xlsx 文件,所以使用 XSSF

/**
     * 读取模板生成excel
     * @param busiDate:业务日期
     * @param unitCode:监控单元
     * @param excelTemplateName:模板名
     * @param outExcelName:文件输出名
     * @param sheetName:要插入的sheet名
     * @param sourceRowNum:要插入数据的行号
     * @param list:要插入的数据,map中属性的顺序须和模板中的列保持一致
     * @return string:生成excel的路径
     * @Description XSSF读到excel的行和列的起始下标都是0,方法输入的行号是从1开始的
     */
public String writeExcel(String busiDate, String unitCode, String excelTemplateName, String outExcelName, String sheetName, int sourceRowNum, List<Map<String, String>> list) throws IOException {
   if(list.size() == 0){
       return "";
    }
    /* 模板path */
    String excelTemp = properties.getMail().getAttachTemplate() + "/" +excelTemplateName;
    /* 生成excel的文件名 */
    String excelName = new String(StringUtils.replace(outExcelName, "${fileName}", busiDate).getBytes(), "UTF-8");
    /* 创建excel */
    File excelPathName = creatSpecialExcel(excelName, unitCode);
    /* 读取excel模板 */
    XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(excelTemp + ".xlsx"));
    XSSFSheet sheet = wb.getSheet(sheetName == null ? "Sheet1":sheetName);
    /* 输入的目标行是excel的目标行从1开始,实质上的目标行是从0开始 */
    sourceRowNum--;
    for(int i = sourceRowNum; i<sourceRowNum+list.size(); i++){
        if(i == sourceRowNum){
            continue;
        }
        /* 如果目标位置下面还有模板,则从i行开始,到最后一行,全部下移一行;如没有模板则直接在目标位置创建新行 */
        if(sheet.getLastRowNum() > i){
            sheet.shiftRows(i, sheet.getLastRowNum(), 1, true, false);
            sheet.createRow(i);
        }
    }
    /* 数据单元格样式 */
    XSSFCellStyle cellStyle = sheet.getRow(sourceRowNum).getCell(0).getCellStyle();
    /* 填充数据 */
    for(int i=0; i<list.size(); i++){
        Set<Map.Entry<String,String>> entrySet = list.get(i).entrySet();
        XSSFRow row = sheet.createRow(sourceRowNum + i);
        int j=0;
        for(Map.Entry<String,String> entry : entrySet){
            XSSFCell cell = row.createCell(j);
            cell.setCellStyle(cellStyle);
            cell.setCellType(CellType.STRING);
            cell.setCellValue(entry.getValue());
            j++;
        }
    }
    log.debug("输出Excel文件");
    FileOutputStream output=new FileOutputStream(new String(excelPathName.getPath().getBytes(), "UTF-8"));
    try{
        wb.write(output);
    } catch (IOException e) {
        log.debug("生成附件Excel失败," + e.getMessage());
        throw new IOException("IOException:特殊excel生成失败");
    } finally {
        wb.close();
        output.close();
    }
    log.debug(unitCode + "完成特殊excel生成...");
    return createProxyHtmlPath(excelPathName, unitCode);
}

/**
 * 文件映射地址:根据WINDOWS和LINUX系统不同转换路径
 */
private String createProxyHtmlPath(File temp, String unitCode) {
    if (SystemUtils.IS_OS_LINUX) {
        return FilenameUtils.concat(StringUtils.replace(StringUtils.replace(properties.getMail().getProxyAttach(), "${date}", LocalDate.now().format(DateTimeFormatter.ISO_DATE)),"${unitCode}", unitCode), temp.getName());
    } else if (SystemUtils.IS_OS_WINDOWS) {
        return temp.getPath();
    } else {
        throw Tools.newException("目前只支持Windows和Linux环境");
    }
}

/**
 * 创建Excel
 */
private File creatSpecialExcel(String fileName, String unitCode) throws IOException {
    try {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(Utility.DATETIME_FORMAT_DEFAULT_MS);
        String path = StringUtils.replace(properties.getMail().getAttach(), "${date}", LocalDate.now().format(DateTimeFormatter.ISO_DATE));
        String basePath = StringUtils.replace(path, "${unitCode}", unitCode);
        FileUtils.forceMkdir(FileUtils.getFile(basePath));
        return FileUtils.getFile(basePath, StringUtils.join(fileName, ".xlsx"));
    }catch (Exception e){
        throw new IOException("生成特殊模板excel失败");
    }
}