使用Apache poi

时间:2017-06-07 05:25:30

标签: java excel apache-poi

我正在尝试使用POI下载Excel文件。正在下载excel文件作为响应的附件。我提到了Stack Overflow上的其他问题,其中的答案主要是尝试不同的内容类型,我尝试了所有提到的不同内容类型,但仍然下载的Excel文件已损坏。

另外,当我尝试使用相同的代码在文件系统上编写Excel时(仅将更改写入文件系统而不是作为附件返回),正确创建了文件系统上生成的excel并没有腐败。只有当我尝试使用HTTP响应返回它时,excel文件才会被破坏。

以下是我用于excel下载的代码:

MainController.java

if (downloadFlag) {
            response = reportsService.initializeXLSContent(response, "Tests_By_Day", fromDate, toDate);
            List<String> columnNames = new ArrayList<>();
            columnNames.add("Day");
            columnNames.add("Tests Count");
            populateAndDispatch(response, result, columnNames);
            return null;
        } 

initializeXLSContent方法

public HttpServletResponse initializeXLSContent(HttpServletResponse response, String fileName, Date startDate,
        Date endDate) {
    response.setContentType("application/force-download");
    StringBuilder reportName = new StringBuilder(fileName);
    Calendar calendar = Calendar.getInstance();
    if (null != startDate) {
        calendar.setTime(startDate);
        reportName = reportName.append("_" + calendar.get(Calendar.YEAR) + "_" + (calendar.get(Calendar.MONTH) + 1)
                + "_" + calendar.get(Calendar.DAY_OF_MONTH));
    }
    if (null != endDate) {
        calendar.setTime(endDate);
        reportName = reportName.append("_" + calendar.get(Calendar.YEAR) + "_" + (calendar.get(Calendar.MONTH) + 1)
                + "_" + calendar.get(Calendar.DAY_OF_MONTH));
    }
    reportName.append(".xlsx");
    response.setHeader("Content-Disposition", "attachment;filename=" + reportName.toString());
    response.setHeader("Content-Transfer-Encoding", "binary");
    return response;
}

populateAndDispatch方法

private void populateAndDispatch(HttpServletResponse response, List<ChartData> chartData,
        List<String> columnNames) {
    List<ArrayList<String>> reportData = new ArrayList<>();
    switch (columnNames.size()) {
    case 2:
        twoColumnPopulate(chartData, reportData);
        break;
    case 3:
        threeColumnPopulate(chartData, reportData);
        break;
    }
    XSSFWorkbook workbook = reportsService.generateContentXLS(reportData, columnNames);
    response = reportsService.dispatchXLSContent(response, workbook);

twoColumnPopulate方法

private void twoColumnPopulate(List<ChartData> chartData, List<ArrayList<String>> reportData) {
    for (ChartData rowData : chartData) {
        ArrayList<String> tempRowData = new ArrayList<>();
        tempRowData.add(rowData.getxData());
        tempRowData.add(rowData.getyData());
        reportData.add(tempRowData);
    }
}

generateXLSContent方法

public XSSFWorkbook generateContentXLS(final List<ArrayList<String>> sheetData, List<String> columnNames) {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet();
        XSSFRow headerRow = sheet.createRow(0);
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontHeightInPoints((short) 14);
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
        style.setFont(font);
        int i = 0; // i is used to iterate over rows
        for (String columnName : columnNames) {
            Cell cell = headerRow.createCell(i++);
            cell.setCellValue(columnName);
            cell.setCellStyle(style);
        }
        int j;
        int k = 1; // j is used to iterate over columns and k is used to count
                    // no.of rows
        for (ArrayList<String> rowData : sheetData) {
            XSSFRow row = sheet.createRow(k++);
            for (j = 0; j < i; j++) {
                row.createCell(j).setCellValue(rowData.get(j));
            }
        }
        return workbook;
    }

dispatchXLSContent方法

public HttpServletResponse dispatchXLSContent(HttpServletResponse response, XSSFWorkbook workbook) {
    try {
        workbook.write(response.getOutputStream());
        response.getOutputStream().flush();
        workbook.close();
    } catch (IOException ie) {
        LOGGER.error("IOException occurred in dispatchXLSContent: ", ie);
    }
    return response;
}

我发现有一件有趣的事情是,我创建了一个示例API来测试这个excel下载功能,并且它在相同的设置下运行良好,但在我的这个特定API中没有。以下是该示例API的代码。

public void testDownload(HttpServletResponse response) throws IOException {
    List<String> test = new ArrayList<>();
    test.add("A");
    test.add("B");
    test.add("C");
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet();
    XSSFRow headerRow = sheet.createRow(0);
    Cell cell1 = headerRow.createCell(0);
    cell1.setCellValue("Header 1");
    Cell cell2 = headerRow.createCell(1);
    cell2.setCellValue("Header 2");
    XSSFRow row = sheet.createRow(0);
    row.createCell(0).setCellValue("Cell 1");
    row.createCell(1).setCellValue("Cell 2");
    row = sheet.createRow(1);
    row.createCell(0).setCellValue("Cell 1");
    row.createCell(1).setCellValue("Cell 2");
    response.setHeader("Content-Disposition", "attachment;filename=hello.xlsx");
    response.setHeader("Content-Transfer-Encoding", "binary");
    response.setContentType("application/force-download");
    workbook.write(response.getOutputStream());
    response.getOutputStream().flush();
    workbook.close();
}

在这种情况下,Excel不会被破坏并正在正确下载。

0 个答案:

没有答案