JAVA: экспорт данных (из базы данных) в Excel и отправка их на сторону клиента - PullRequest
4 голосов
/ 15 февраля 2012

Как следует из названия, мне нужно поместить некоторые данные (которые я получил из базы данных) в таблицу Excel, а затем отправить их на сторону клиента, чтобы пользователь мог сохранить, открыть или отменить действие.

Я видел несколько статей по этому поводу, самая близкая из них: Как я могу заставить пользователя загрузить мой файл? (Java, MVC, Excel, POI) . Ссылаясь на ссылки, предоставленные Стивенсом, я опробовал следующий код:

public String execute(){
    setContentDisposition("attachment; filename=\"" + ename + "\"");
    try{
        ServletContext servletContext = ServletActionContext.getServletContext();
        String filePath = servletContext.getRealPath("/WEB-INF/template/excel/mytemplate.xls");
        File file = new File(filePath);
        Workbook wb = WorkbookFactory.create(new FileInputStream(file));
        Sheet sheet = wb.getSheetAt(0);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        wb.write(baos);
        InputStream excelStream;
        excelStream = new ByteArrayInputStream(baos.toByteArray());
    }catch(Exception e){
        System.out.println(e.getMessage());
    }
    return SUCCESS;
}

Здесь, во-первых, WorkbookFactory не определено. Во-вторых, я не мог правильно понять, как работает код.

Я также нашел эту ссылку: http://www.roseindia.net/answers/viewqa/Java-Beginners/14930-How-to-export-data-from-database-to-excel-sheet-by-using-java--in-standalone-project.html. Но здесь файл Excel сохраняется на сервере. Я хочу, чтобы файл не сохранялся на стороне сервера, он должен идти непосредственно на стороне клиента

(если это помогает) Я использую: Struts 2 Framework, Hibernate

Я открыт для использования других вещей, таких как POI API, jQuery или любых других полезных вещей.

Почему-то не могу использовать displayTag.

Javascript будет моим последним средством (хотя я и реализовал его), потому что он требует изменения некоторых настроек безопасности браузера по умолчанию (если этого можно избежать, я также открыт для javascript).

Посоветуйте, пожалуйста, как мне поступить сейчас.

Спасибо !!

РЕДАКТИРОВАТЬ:

    <result-types>
        <result-type name="jsp" class="org.apache.struts2.views.jsp"/>
        <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"/>
        <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
    </result-types>
    <action name="myActionName" class="package.myActionClass">
         <result type="stream">
            <param name="contentType">"application/vnd.ms-excel"</param>
            <param name="inputName">excelStream</param>
            <param name="contentDisposition">contentDisposition</param>
            <param name="bufferSize">1024</param>
         </result>
    </action>

Ошибка при выполнении действия:

java.lang.reflect.InvocationTargetException

java.lang.IncompatibleClassChangeError: Class org.apache.poi.hssf.usermodel.HSSFWorkbook does not implement the requested interface org.apache.poi.ss.usermodel.Workbook

Ответы [ 2 ]

10 голосов
/ 16 февраля 2012

Хорошо.Итак, наконец, я преодолел все препятствия и нашел способ сделать это.

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

Итак, вот как это сделать (я вычеркнул детали из моего исходного кода, чтобы вы могли его легко понять).

В файле действий сначала необходимо создать объект HSSFWorkbook, поместить на него данные, а затем, не сохраняя их на диск на сервере, отправить их клиенту с помощью inputtream.

Код файла действия:

public String execute(){

    setContentDisposition("attachment; filename=\"" + ename + ".xls\"");

    try{
        HSSFWorkbook hwb=new HSSFWorkbook();
        HSSFSheet sheet =  hwb.createSheet("new sheet");

        //////You can repeat this part using for or while to create multiple rows//////
            HSSFRow row = sheet.createRow(rowNum);
            row.createCell(0).setValue("col0");
            row.createCell(1).setValue("col1");
            row.createCell(2).setValue("col2");
            row.createCell(3).setValue("col3");
            .
            .
            .
        ///////////////////////////////////////////////////////////////////////////////

        ///////////////////////////////////////////////////////////////////////////////
        //////Now you are ready with the HSSFworkbook object to be sent to client//////
        ///////////////////////////////////////////////////////////////////////////////

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        hwb.write(baos);
        excelStream = new ByteArrayInputStream(baos.toByteArray());

        ///////////////////////////////////////////////////////////////////////////////
        ////Here HSSFWorkbook object is sent directly to client w/o saving on server///
        ///////////////////////////////////////////////////////////////////////////////
    }catch(Exception e){
        System.out.println(e.getMessage());
    }
    return SUCCESS;
}

Теперь в файле struts-config просто напишите (обратите внимание, что excelStream и contentDisposition были установлены в самом действии, а тип результата здесь org.apache.struts2.dispatcher.StreamResult):

    <action name="actionName" class="actionClass">
        <result type="stream">
            <param name="contentType">"application/vnd.ms-excel"</param>
            <param name="inputName">excelStream</param>
            <param name="contentDisposition">contentDisposition</param>
            <param name="bufferSize">1024</param>
        </result>
    </action>

ThatsЭто.Теперь, когда действие выполнено, пользователю будет предложено сохранить или открыть файл.

:)

2 голосов
/ 16 февраля 2012

На вашем пути к классам есть две разные копии POI, одна старая и одна новая.Вот почему вы получаете исключение java.lang.IncompatibleClassChangeError: Class org.apache.poi.hssf.usermodel.HSSFWorkbook не реализует запрошенный интерфейс org.apache.poi.ss.usermodel.Workbook -вы скомпилировали новую копию, но во время выполнения она находит несколько новых и старых jar-файлов.

Это описано в POI FAQ .В идеале вы должны просто посмотреть на все банки в вашей настройке и убрать старый POI.Если нет, то в записи FAQ *1007* POI есть пример кода, который вы можете использовать, чтобы заставить JVM распечатать, откуда были загружены классы POI.Это покажет вам имя файла JAR, и вы можете удалить старое.

...