我使用apache poi创建Excel文件。但当我打开excell文件时,它表示格式错误的文件需要恢复

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

标签: java excel apache apache-poi

当我打开文件时,它显示格式错误的文件并需要恢复。当我按下它没关系它打开,我写的数据就在那里。它说**(Excel完成了文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃。)**我想纠正此错误。如何将这个格式错误的excel文件转换为格式良好的Excel文件?

这是写作部分。

 ArrayList<Schedule> schds = serviceResponce.getSchedules();
                    XSSFWorkbook workbook = new XSSFWorkbook();
                    XSSFSheet sheet = workbook.createSheet("sheet");
                    CellStyle styleHeaders;
DataFormat format = workbook.createDataFormat();
CellStyle styleDataCells;
                    DataFormatter downloadForatter=new DataFormatter();
                    styleDataCells = workbook.createCellStyle();
                    for (Schedule sch : schds) {
                        Row row = sheet.createRow(++rowCount);
                        Cell cellScheduleId = row.createCell(0);
                        Cell cellRouteId = row.createCell(1);
                        Cell cellDepTime = row.createCell(2);
                        Cell cellArrTime = row.createCell(3);
                        Cell cellFromTo = row.createCell(4);
                        Cell cellDay = row.createCell(5);
                        Cell cellStatus = row.createCell(6);

                        downloadForatter.formatCellValue(cellDay);
                        cellScheduleId.setCellValue(Integer.parseInt(sch.getSchedule_id()));
                        styleDataCells.setDataFormat(format.getFormat("0"));
                        cellScheduleId.setCellStyle(styleDataCells);

                        cellRouteId.setCellValue(Integer.parseInt(sch.getRoute_id()));
                        styleDataCells.setDataFormat(format.getFormat("0"));
                        cellRouteId.setCellStyle(styleDataCells);

                        cellDepTime.setCellValue(sch.getDeptature_time());
                        styleDataCells.setDataFormat(format.getFormat("hh:mm"));
                        cellDepTime.setCellStyle(styleDataCells);

                        cellArrTime.setCellValue(sch.getArrival_time());
                        styleDataCells.setDataFormat(format.getFormat("hh:mm"));
                        cellArrTime.setCellStyle(styleDataCells);

                        cellFromTo.setCellValue(sch.getFrom_to());
                        styleDataCells.setDataFormat(format.getFormat("@"));
                        cellFromTo.setCellStyle(styleDataCells);

                        cellDay.setCellValue(sch.getDay());
                        styleDataCells.setDataFormat(format.getFormat("@"));
                        cellDay.setCellStyle(styleDataCells);

                        if (sch.getStatus().equals("Y")) {
                            cellStatus.setCellValue("Active");
                            styleDataCells.setDataFormat(format.getFormat("@"));
                            cellStatus.setCellStyle(styleDataCells);
                        } else {
                            cellStatus.setCellValue("Inactive");
                            styleDataCells.setDataFormat(format.getFormat("@"));
                            cellStatus.setCellStyle(styleDataCells);
                        }
                    }
                    try {
                        String downloadPath = getServletContext().getRealPath("/") + "ExpSchedules.xlsx";
                        File excelFile = new File(downloadPath);
                        if (excelFile != null && excelFile.exists()) {
                            excelFile.delete();
                        }
                        excelFile.createNewFile();
                        FileOutputStream outputStream = new FileOutputStream(downloadPath);
                        workbook.write(outputStream);
                        workbook.close();
                        log.info("path " + downloadPath);

//                        
                        String original_filename = "ExpSchedules.xlsx";
                        ServletContext sc = this.getServletContext();
                        InputStream is = new FileInputStream(excelFile);
                        if (is != null && is.available() > 0) {
                            log.info("IS is not null");
                        } else {
                            log.info("IS is null");
                        }
                        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                        response.setHeader("Content-Disposition", "attachment; filename=\"" + original_filename + "\"");
//                        
//                        File file = new File(downloadPath);
//                        FileInputStream fileIn = new FileInputStream(file);
                        ServletOutputStream outA = response.getOutputStream();
//
                        byte[] outputByte = new byte[4096];
//
                        while (is.read(outputByte, 0, 4096) != -1) {
                            outA.write(outputByte, 0, 4096);
                        }
                        is.close();
                        outA.flush();
                        outA.close();

1 个答案:

答案 0 :(得分:3)

假设您正在谈论从site_id equipment_number cmd_name date_logged 下载的文件,而不是您在服务器上创建的文件。

问题与代码的以下部分有关。

Servlet

您总是尝试在响应输出流中写入byte[] outputByte = new byte[4096]; while (is.read(outputByte, 0, 4096) != -1) { outA.write(outputByte, 0, 4096); } 个字节。您的文件内容永远不会是4096的倍数,此代码应修改如下。

4096

除此之外,此代码存在多个问题。检查以下

  1. 您不应该关闭响应输出流,让Servlet容器处理它。 Rule is if you didn't open it, don't close it
  2. 您预计一次只有一个用户会下载文件,但Servlet容器是多线程环境。这意味着多个用户可以同时调用下载Servlet。然后这段代码将写入两个不同线程中的同一文件,这将导致异常或将损坏文件。您需要为输出文件创建一个随机名称,或者更好地使用File.createTempFile()。在将其刷新到响应输出流后,将其删除。
  3. 最后请模块化代码,将文件创建代码分成另一种方法。