change default format dataExporter in Primefaces

2020-06-29 08:07发布

问题:

I want to use to generate a pdf dataexporter, use the method preprocessor to insert some content. By giving the type letter size page assimilates well as formats of texts. Then make a page break to put the chart on a new page, right there is the problem that generates the second page with other size and also find a way to change the font size of the text of the exported table.

<h:commandLink>  
      <p:graphicImage value="/images/pdf.png"/> 
             <p:dataExporter type="pdf" target="dataTableAddDetalles" fileName="pdf" preProcessor="#{serviciosMB.preProcessPDF}"/>  
</h:commandLink>

backing bean

 public void preProcessPDF(Object document) throws Exception {
    try {
        Document pdf = (Document) document;
        pdf.open();
        pdf.setPageSize(PageSize.LETTER);

        ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
        String logo = servletContext.getRealPath("") + File.separator + "images" + File.separator + "header.gif";

       // pdf.add(Image.getInstance(logo));
        pdf.add(new Paragraph("EMNI", FontFactory.getFont(FontFactory.HELVETICA, 22, Font.BOLD, new Color(0, 0, 0))));
        SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");

        pdf.add(new Phrase("Fecha: " + formato.format(new Date())));
        pdf.newPage();
    } catch (Exception e) {
        //JsfUtil.addErrorMessage(e, e.getMessage());
    }
}

回答1:

The primefaces documentation (as of 4.0) does not mention any ability to write a custom data exporter, only pre & post processors, which in the case of PDF prevents you from doing extensive modifications to data, etc.

But what you can do is create a package in your project called

org.primefaces.component.export

and copy ExporterFactory.java from primefaces source. You can then replace the original PDFExporter call with your own implementation.

The exporter implementation is fairly simple. It uses iText library (although an outdated version) and you can easily extend it to your needs.

An obvious problem with this approach is that you may have to be extra careful when (and if) you are updating your primefaces library in the future.



回答2:

You can't do what you want using dataexporter, you need to change your code to:

<h:commandLink actionListener="#{serviciosMB.createPDF}">
    <p:graphicImage value="/images/pdf.png" />
</h:commandLink>

And your managed bean:

public void createPDF() {
    try { //catch better your exceptions, this is just an example
        FacesContext context = FacesContext.getCurrentInstance();
        Document document = new Document();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, baos);

        if (!document.isOpen()) {
            document.open();
        }

        PdfPTable pdfTable = exportPDFTable();
        document.add(pdfTable);

        //Keep modifying your pdf file (add pages and more)

        document.close();
        String fileName = "PDFFile";

        writePDFToResponse(context.getExternalContext(), baos, fileName);

        context.responseComplete();

    } catch (Exception e) {
        //e.printStackTrace();          
    }
}

exportPDFTable method:

private PdfPTable exportPDFTable() {
    int numberOfColumns = 1;
    itemOfList item = null;
    PdfPTable pdfTable = new PdfPTable(numberOfColumns);
    pdfTable.setWidthPercentage(100);
    BaseFont helvetica = null;
    try {
        helvetica = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED);
    } catch (Exception e) {
        //font exception
    }
    Font font = new Font(helvetica, 8, Font.NORMAL);
    pdfTable.addCell(new Paragraph("columnName", font));        

    for (int i = 0; i < lstPdfTable.size(); i++) { //lstPdfTable is the list from your datatable. A List of "itemOfList" type
        item = new itemOfList();
        item = lstPdfTable.get(i);
        //pdfTable.addCell(new Paragraph('any_string_field', font));
        pdfTable.addCell(new Paragraph(item.getStringField(), font));           
    }
    return pdfTable;
}

and writePDFToResponse method is:

private void writePDFToResponse(ExternalContext externalContext, ByteArrayOutputStream baos, String fileName) {
    try {
        externalContext.responseReset();
        externalContext.setResponseContentType("application/pdf");
        externalContext.setResponseHeader("Expires", "0");
        externalContext.setResponseHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
        externalContext.setResponseHeader("Pragma", "public");
        externalContext.setResponseHeader("Content-disposition", "attachment;filename=" + fileName + ".pdf");
        externalContext.setResponseContentLength(baos.size());
        OutputStream out = externalContext.getResponseOutputStream();
        baos.writeTo(out);
        externalContext.responseFlushBuffer();
    } catch (Exception e) {
        //e.printStackTrace();
    }
}