Info-System

Jasper Reports i servlet eksportujący do Excela

Email Drukuj PDF

Servlet generujący pliki xls (Excel) przy pomocy Jasper Reports

Tym, co się śpieszą podpowiem, że kod servletu jest na końcu. W moim edytorze formularzy i ankiet internetowych chciałem dodać możliwość eksportowania plików xls zawierających tabelę z zebranymi danym. Wszystko przebiegło sprawnie, ale ... Zawsze jest jakieś "ale". Wszystko było ok na moim komputerze roboczym(Windows), ale nie działało na moim serwerze produkcyjnym, który działa na linuxie (a dokładniej na Gentoo).

Każdy wygenerowany plik xls był pusty. Byłem dość mocno sfrustrowany, bo błąd nie pojawiał się w logach JBoss’a. Sprawdziłem kilka tropów: niezawodność DynamicJasper (użyłem go, aby uzyskać dynamiczne kolumny), błędy związane z zamknięciem strumienia, określeniem długości odpowiedzi, itp. Niestety wszystko wskazywało na to, że chochlik siedzi gdzie indziej.

Byłem naprawdę przygnębiony, bo dość długo nie posunąłem się na przód. Nagle zdałem sobie sprawę, że standardowe logowanie (log4j) do pliku określone w JBoss pokazuje nieco inne rzeczy niż logger piszący do konsoli, zajrzałem do drugiego log serwera a tam siedzi i uśmiecha się taka pociecha:

net.sf.jasperreports.engine.util.JRFontNotFoundException: Font 'Arial' is not available to the JVM. See the Javadoc for more details.
      at net.sf.jasperreports.engine.util.JRFontUtil.checkAwtFont(JRFontUtil.java:339)
      at net.sf.jasperreports.engine.util.JRStyledText.getAwtAttributedString(JRStyledText.java:226)
      at net.sf.jasperreports.engine.fill.TextMeasurer.measure(TextMeasurer.java:362)
      at net.sf.jasperreports.engine.fill.JRFillTextElement.chopTextElement(JRFillTextElement.java:1129)

Okazało się, że Gentoo nie posiada popularnych czcionek. Wstyd chłopaki, nie dziwcie się potem, że Linux nie trafia pod strzechy! Z drugiej rzeba przyznać, że kolesie z gentoo postrali się o to by instalacja brakujących fontów była naprawdę prosta. Wystarczy wpisać "emerge corefonts" w konsolę i gotowe. To była bolesna lekcja, ale teraz wiem, że należy zwrócić większą uwagę na konfigurację logerów serwera produkcyjnego.

Jak piszę to teraz, to brzmi to jak oczywista oczywistość. Damn!

O to kod servletu:

            import java.io.ByteArrayOutputStream;
            import java.io.IOException;
            import java.text.SimpleDateFormat;
            import java.util.ArrayList;
            import java.util.Date;
            import java.util.HashMap;
            import java.util.List;
            import java.util.Locale;
            import java.util.Map;
         
            import javax.servlet.ServletException;
            import javax.servlet.ServletOutputStream;
            import javax.servlet.http.HttpServlet;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            
            import net.sf.jasperreports.engine.JRDataSource;
            import net.sf.jasperreports.engine.JRException;
            import net.sf.jasperreports.engine.JRExporterParameter;
            import net.sf.jasperreports.engine.JasperPrint;
            import net.sf.jasperreports.engine.data.JRMapCollectionDataSource;
            import net.sf.jasperreports.engine.export.JRXlsExporter;
            import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
            import net.sf.jasperreports.engine.util.JRProperties;
            import net.sf.jasperreports.engine.util.JRStyledText;
            
            import org.apache.log4j.Logger;
            import org.jboss.seam.Component;
            import org.jboss.seam.log.Log;
            
            import ar.com.fdvs.dj.core.DynamicJasperHelper;
            import ar.com.fdvs.dj.core.layout.ListLayoutManager;
            import ar.com.fdvs.dj.domain.DynamicReport;
            import ar.com.fdvs.dj.domain.builders.ColumnBuilderException;
            import ar.com.fdvs.dj.domain.builders.FastReportBuilder;
            
            import com.infosystem.forms.entity.Field;
            import com.infosystem.forms.entity.Submit;
            import com.infosystem.forms.forms.FieldUtils;
            import com.infosystem.utility.HTMLCleaner;
            
            public class CSVExportServletDEmo extends HttpServlet {
            
                private ExportDao exportDao = new ExportDao();
            
                private List<Field> fields;
                private ServletOutputStream outputStream;
                private Logger log = Logger.getLogger(CSVExportServletDEmo.class);
            
                public void doGet(HttpServletRequest request, HttpServletResponse response)
                        throws ServletException, IOException {
                    prepareFields(request, response);
                    try {
                        if (exportDao.isFormResultsAllowedForPublic()) {
                            setResponseProperties(response);
                            createResponse(response);
                        }
                    } catch (Exception e) {
                       logger.error(e);
                    } finally {
                        outputStream.flush();
                        outputStream.close();
                    }
                }
            
                private void prepareFields(HttpServletRequest request,
                        HttpServletResponse response) throws IOException {
                    response.reset();
                    exportDao = new ExportDao();
                    setFormId(request.getParameter("formId"));
                    setChosenField(request.getParameter("chosenFields"));
                    outputStream = response.getOutputStream();
                }
            
                private void setResponseProperties(HttpServletResponse response) {
                    response.setContentType("application/vnd.ms-excel");
                    response.setHeader("Content-Disposition", "inline; filename="
                            + getFileName());
                }
            
                public void createResponse(HttpServletResponse response) throws IOException {
                    DynamicReport dr;
                    try {
                        dr = prepareReport();
                        JRDataSource ds = loadData();
                        ByteArrayOutputStream stream = loadReportAndExport(dr, ds);
                        stream.flush();
                        stream.close();
                        byte[] bytes = stream.toByteArray();
                        response.setContentLength(bytes.length);
                        log.error(bytes.length);
                        outputStream.write(bytes, 0, bytes.length);
                    } catch (JRException e) {
                        log.error(e.getMessage(), e);
                    } catch (ColumnBuilderException e) {
                        log.error(e.getMessage(), e);
                    } catch (ClassNotFoundException e) {
                        log.error(e.getMessage(), e);
                    }
                }
            
                public DynamicReport prepareReport() throws ColumnBuilderException,
                        IOException, ClassNotFoundException {
                    FastReportBuilder drb = new FastReportBuilder();
                    drb.setResourceBundle("forms");
                    drb = createColumns(drb);
                    drb.setTitle(exportDao.getFormTitle())
                            .setPrintBackgroundOnOddRows(true).setIgnorePagination(true);
                    return drb.build();
                }
            
                public JRDataSource loadData() throws JRException {
                    List<Map<String, String>> rows = new ArrayList<Map<String, String>>();
            
                    return new JRMapCollectionDataSource(rows);
                }
            
                private ByteArrayOutputStream loadReportAndExport(DynamicReport dr,
                        JRDataSource ds) throws JRException {
                    JasperPrint jasperPrint = DynamicJasperHelper.generateJasperPrint(dr,
                            new ListLayoutManager(), ds);
                    ByteArrayOutputStream xlsReport = new ByteArrayOutputStream();
                    JRXlsExporter exporter = new JRXlsExporter();
                    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, xlsReport);
                    exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,
                            Boolean.FALSE);
                    exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE,
                            Boolean.TRUE);
                    exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,
                            Boolean.FALSE);
                    exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_GRAPHICS,
                            Boolean.FALSE);
                    exporter.exportReport();
                    return xlsReport;
                }
            
                private FastReportBuilder createColumns(FastReportBuilder drb)
                        throws IOException, ColumnBuilderException, ClassNotFoundException {
                    fields = exportDao.getFields();
                    for (Field field : fields) {
                        drb = drb.addColumn(HTMLCleaner.getStringWithoutTags(field
                                .getDescription()), String.valueOf(field.getId()),
                                String.class, 100);
                    }
                    return drb;
                }
            
                public Log getLogger() {
                    return (Log) Component.getInstance(Log.class);
                }
            
                public String getFileName() {
                    return exportDao.getFormName() + "_" + new Date()
                            + ".xls";
                }
            
                public ExportDao getExportDao() {
                    return exportDao;
                }
            
            }

 

Dodaj komentarz


Kod antysapmowy
Odśwież

Joomlart