立诚勿怠,格物致知
It's all about connecting the dots

Java导出含有多个工作表(sheet)的excel文件

最近碰到一个需求,后台有个台账导出的功能,以前所有数据都是导出到excel的一个sheet中集中显示的,这次的需求是要根据列表中的签单机构名称来分sheet导出,即签单机构相同的台账在同一个sheet中显示。把完成这个需求的核心代码去掉业务逻辑后就变成了下面这样的代码。需要说明的一点是,像这样的需求不可以真的是根据“名称”来分sheet导出的,你应该根据id这种不会重复的字段来作为分类依据,“名称”理论上是存在同名的可能性的。Talk is cheap, show you the code right now:

//  数字类型
List<String> numericList = null;

/**
 * 根据原始列表中的TYPE字段分sheet导出(生成一个含有多个sheet的excel文件,相同TYPE值的条目对应一个sheet)
 * @param templetePath  模板文件地址(该模板文件第一个sheet里提供了要生成的excel文件表头部分的内容)
 * @param columns       excel列表中要显示的各个列对应的名字
 * @param statisticList 原始列表数据,每条里都含有一个TYPE字段
 * @param worksheet     要输出的excel文件工作表名
 * @param os            通过response.getOutputStream获得的东西
 * @param cellSize      列数(比如32)
 */
public void helloMultipleSheetExport(String templetePath, String[] columns, List<Map<String, Object>> statisticList, String worksheet, OutputStream os, int cellSize) {
    // 新文件写入数据
    File newFile = createNewFileByPath(templetePath);
    // 写入行的起始行.
    Long startRow = 4L;
    Long maxRows = 60000L;
    InputStream is = null;
    XSSFWorkbook workbook = null;
    XSSFSheet sheet = null;
    // 按TYPEID机构重新组织statisticList里的数据
    Map<String, Boolean> backup = new HashMap<>();
    List<List<Map<String, Object>>> typesList = new ArrayList<>();
    for (Map<String, Object> item : statisticList) {
        Object oTypeId = item.get("TYPEID");
        String sTypeId = (String) oTypeId;
        if (!backup.containsKey(orgName)) {
            List<Map<String, Object>> ordersByCurType = new ArrayList<>();
            for (Map<String, Object> order : statisticList) {
                if (order.get("TYPE").equals(oTypeId)) {
                    ordersByCurType.add(order);
                }
            }
            typesList.add(ordersByCurType);
            backup.put(sTypeId, true);
        }
    }
    try {
        // 将excel文件转为输入流
        is = new FileInputStream(newFile);
        // 创建一个workbook
        workbook = new XSSFWorkbook(is);
        // 清空workbook中的所有sheet(除了模板excel中的第一个sheet,里面有表头内容,需要拷贝到其他sheet中)
        for (int i = workbook.getNumberOfSheets(); i > 1; i--) {
            workbook.removeSheetAt(i - 1);
        }
        // 复制第一个sheet的表头
        int numOfOrgs = typesList.size();
        for (int n = 1; n < numOfOrgs; n++) {
            workbook.cloneSheet(0);
        }
        // 每个TYPEID单独一个sheet
        for (int n = 0; n < numOfOrgs; n++) {
            List<Map<String, Object>> ordersByCurType = typesList.get(n);
            sheet = workbook.getSheetAt(n);
            workbook.setSheetName(n, ordersByCurType.get(0).get("TYPENAME").toString());
            int rowSize = ordersByCurType.size();
            for (int m = 0; m < rowSize; m++) {
                Map<String, Object> map = ordersByCurType.get(m);
                XSSFRow row = sheet.createRow(m + startRow.intValue());
                for (int i = 0; i < cellSize; i++) {
                    String column = columns[i];
                    if (StringUtils.isBlank(column)) {
                        continue;
                    }
                    String value = map.get(column) + "";
                    if(!"null".equals(value) && StringUtils.isNotBlank(value)){
                        setCellDataType(cell, column, value);
                    }else{
                        cell.setCellValue("");
                    }
                }
            }
        }
        workbook.write(os);
    } catch (Exception e) {
        e.printStackTrace();
        logger.error("数据导出失败!失败原因为:" + e.getMessage());
    } finally {
        try {
            if (null != is) {
                is.close();
            }
            // 删除生成的临时文件
            newFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
private void setCellDataType(Cell cell,String columnName,String value) {
    if (CollectionUtils.isEmpty(numericList)) {
        numericList = new ArrayList<>();
        numericList.add("VC2BIPREMIUM");
        numericList.add("VC2CIPREMIUM");
        numericList.add("VC2TAX");
        numericList.add("VC2TOTALPRICE");
        numericList.add("VC2PAYPRICE");
        numericList.add("VC2TRANSAMOUNT");
        numericList.add("VC2ADVANCE");
        numericList.add("VC2CMISCASH");
    }
    if (StringUtils.isNotBlank(columnName) && numericList.contains(columnName)) {
        cell.setCellValue(Double.parseDouble(value));
    } else {
        cell.setCellValue(value);
    }
}

/**
 * 根据excel模板文件创建要下载的文件
 * @param  sysPath excel模板文件路径
 * @return         文件
 */
public File createNewFileByPath(String sysPath) {
    // 文件模板路径
    String path = sysPath + "xls/hello.xls";
    File file = new File(path);
    // 保存文件的路径
    String realPath = (sysPath + "xls/temp");
    // 新的文件名
    String newFileName = "hello" + System.currentTimeMillis() + ".xlsx";
    // 判断路径是否存在
    File dir = new File(realPath);
    if (!dir.exists()) {
        dir.mkdirs();
    }
    // 写入到新的excel
    File newFile = new File(realPath, newFileName);
    try {
        newFile.createNewFile();
        // 复制模板到新文件
        fileChannelCopy(file, newFile);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return newFile;
}

private void setCellDataType(Cell cell, String columnName, String value) {
    if (CollectionUtils.isEmpty(numericList)) {
        numericList = new ArrayList<>();
        numericList.add("COLUMNNAME1");
        numericList.add("COLUMNNAME2");
        numericList.add("COLUMNNAME3");
        numericList.add("COLUMNNAME4");
        numericList.add("COLUMNNAME5");
        numericList.add("COLUMNNAME6");
        numericList.add("COLUMNNAME7");
        numericList.add("COLUMNNAME8");
    }
    if (StringUtils.isNotBlank(columnName) && numericList.contains(columnName)) {
        cell.setCellValue(Double.parseDouble(value));
    }else{
        cell.setCellValue(value);
    }
}

 

赞(1) 打赏
文章名称:《Java导出含有多个工作表(sheet)的excel文件》
文章链接:https://www.orzzone.com/java-generate-multiple-sheet-excel.html
商业联系:yakima.public@gmail.com

本站大部分文章为原创或编译而来,对于本站版权文章,未经许可不得用于商业目的,非商业性转载请以链接形式标注原文出处。
本站内容仅供个人学习交流,不做为任何投资、建议的参考依据,因此产生的问题需自行承担。

评论 抢沙发

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力提供更多优质内容!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册