Apache POI — работа с XSSFWorkbok + ответ сервлета

У меня возникают проблемы в моем Java-приложении, чтобы разрешить загрузку файлов XLSX.

следуя примеру, показанному в этой ссылке: Создайте файл Excel для загрузки пользователями с помощью Apache POI. Я попробовал две конфигурации для загрузки/сохранения электронной таблицы.

Сначала с файлом .XLS:

response.setContentType("application/ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=testxls.xls");

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue("Some text");

ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
wb.write(outByteStream);

byte[] outArray = outByteStream.toByteArray();
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();

Это работает.

Затем я попробовал файл XLSX:

response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=testxls.xlsx");

XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
XSSFRow row = sheet.createRow(0);
XSSFCell cell = row.createCell(0);
cell.setCellValue("Some text");

ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
wb.write(outByteStream);

byte[] outArray = outByteStream.toByteArray();
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();

Когда я пытаюсь это сделать, я получаю сообщение: "Excel обнаружил нечитаемое содержимое в файле testxls.xlsx. Вы хотите восстановить содержимое этой книги? ...."

Несмотря на это сообщение, электронная таблица открывается нормально, но я очень хочу удалить это сообщение.

Есть идеи?


person Lucas_Mux    schedule 13.03.2013    source источник
comment
Какой тип outByteStream?   -  person Buhake Sindi    schedule 13.03.2013
comment
Зачем тебе ByteArrayOutputStream? Разве вы не можете просто сделать wb.write(response.getOutputStream()) вместо этого?   -  person Buhake Sindi    schedule 13.03.2013
comment
Я пробовал с org.apache.commons.io.output.ByteArrayOutputStream и java.io.ByteArrayOutputStream   -  person Lucas_Mux    schedule 13.03.2013
comment
Пробовал с wb.write(response.getOutputStream()), но сообщение сохраняется.   -  person Lucas_Mux    schedule 13.03.2013
comment
Попробуйте это superuser.com/questions/401714/   -  person Hardik Mishra    schedule 14.03.2013
comment
Если вы записываете XSSFWorkbook в файл, а не в сервлет, сможет ли Excel открыть его без ошибок? Это позволит вам решить, есть ли у вас проблема с выводом сервлета или проблема с XSSF.   -  person Gagravarr    schedule 01.06.2013


Ответы (2)


Я знаю, что это очень старый (6 лет), но я добрался сюда после обновления некоторого старого кода для перехода с HSSF на XSSF, моя проблема заключалась в отсутствующей банке xmlbeans-3.1.0.jar. Ошибка была записана в журнал локального хоста TomCat java.lang.ClassNotFoundException: org.apache.xmlbeans.XmlObject.

person user1977008    schedule 13.07.2020

Используйте этот код JSP и успешно сгенерируйте файл excel. Я ввел данные в файл excel через базу данных, которую вы также можете ввести вручную.

<%HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet = wb.createSheet();
       try {
        java.sql.Connection con;
        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/custinfo","root","abc");
            Statement st= con.createStatement(); 
            out.println("hello world");
        ResultSet rs=st.executeQuery("select name ,state ,balance,description from customerdata where customerid='"+Id+"'"); 

        HSSFRow row = sheet.createRow((short)0);
        row.createCell((short)0).setCellValue("NAME");
        row.createCell((short)1).setCellValue("STATE");
        row.createCell((short)2).setCellValue("BALANCE");
        row.createCell((short)3).setCellValue("DESCRIPTION");
        while(rs.next())
        {
             out.println("hello world data");       
            HSSFRow row1 = sheet.createRow((short)i);
            row1.createCell((short)0).setCellValue(rs.getString("name"));
            row1.createCell((short)1).setCellValue(rs.getString("state"));
         row1.createCell((short)2).setCellValue(rs.getString(3));
         row1.createCell((short)3).setCellValue(rs.getString(4));
         i=i+1;
        sheet.autoSizeColumn((short)1); 

        }

       }
      catch(SQLException e) {
        out.println("SQLException caught: " +e.getMessage());
      }%>
    // create a small spreadsheet
    <%

    %>
    <% 

    ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
    wb.write(outByteStream);
    byte [] outArray = outByteStream.toByteArray();
    response.setContentType("application/ms-excel");
    response.setContentLength(outArray.length);
    response.setHeader("Expires:", "0"); // eliminates browser caching
    response.setHeader("Content-Disposition", "attachment; filename=testxls.xls");
    OutputStream outStream = response.getOutputStream();
    outStream.write(outArray);
    outStream.flush();

    %>
person amy    schedule 01.06.2013
comment
Но этот пример по-прежнему HSSF, то есть .xls, а не XSSF для .xlsx, как того хочет ОП. Можете ли вы выделить, что здесь отличается, и что, по вашему мнению, имеет значение? - person Rup; 28.04.2014
comment
Основываясь на другом ответе, важно установить длину содержимого. - person Rup; 28.04.2014