问题
I have a Primefaces DataGrid that I export whith Primefaces DataExporter but I can't figure out how to resize the columns.
I added a preporcessor
<p:dataExporter type="pdf" target="tbl" fileName="cars" preProcessor="#{customizedDocumentsView.preProcessPDF}" />
And this is the code in my bean
public void preProcessPDF(Object document) {
        Document pdf = (Document) document;
        pdf.open();
        pdf.setPageSize(PageSize.A4);
        //I need to do something like that
        //PdfPTable table = new PdfPTable(4);
        //float[] columnWidths = new float[] {10f, 20f, 30f, 10f};
        //table.setWidths(columnWidths);
    } 
Is there any way to do this ?
回答1:
Recently I inherited project with many already existing exporters with already set options tags so I needed to find solution that will keep all of them intact.
I got an idea from this accepted answer.
My solution sets column widths via options tag of p:dataExporter so there is no need for pre/post processing. I tested it using Primefaces ver 4.x and up.
Step by step procedure:
- Create new package - org.primefaces.component.exportinside your project.
- From Primefaces git repository fully copy following classes ExporterOptions ,PDFOptions, Exportedfactory and PDFExporter into newly created package. 
- In ExporterOptions add - public float[] getColumnWidths();
- In PDFOptions add - float[] columnWidths;and add getter and setter.
- In ExporterFactory modify line - exporter = new PdfExporter();to- exporter = new CustomPdfExporter();
- Rename PDFExporter class to CustomPDFExporter and keep just following export method fully - public void export(FacesContext context, DataTable table, String filename, boolean pageOnly, boolean selectionOnly, String encodingType,MethodExpression preProcessor, MethodExpression postProcessor, ExporterOptions options) throws IOException
Delete code from other export methods but keep declarations.
- Inside CustomPDFExporter add 2 lines in ExportPdfTable method - protected PdfPTable exportPDFTable(FacesContext context, DataTable table, boolean pageOnly, boolean selectionOnly, String encoding) throws DocumentException { int columnsCount = getColumnsCount(table); PdfPTable pdfTable = new PdfPTable(columnsCount); this.cellFont = FontFactory.getFont(FontFactory.TIMES, encoding); this.facetFont = FontFactory.getFont(FontFactory.TIMES, encoding, Font.DEFAULTSIZE, Font.BOLD); if (this.expOptions != null) { applyFacetOptions(this.expOptions); applyCellOptions(this.expOptions); //line 1 //sets columns column relative widths to iText PdfTable object pdfTable.setWidths(this.expOptions.getColumnWidths()); //line 2 //decreases page margins comparing to original 'Primefaces' layout pdfTable.setWidthPercentage(100); } //....- } 
- Now you are ready to go managed bean and add pdf option. For example - pdfOpt = new PDFOptions(); //add getter and setter too pdfOpt.setFacetBgColor("#F88017"); ... //if, for example, your PDF table has 4 columns //1st column will occupy 10% of table's horizontal width,...3rd - 20%, 4th - 60% float[] columnWidths = new float[]{0.1f, 0.1f, 0.2f, 0.6f}; pdfOpt.setColumnWidths(columnWidths); ...
- Finally your - p:dataExportercomponent should look like this- <p:dataExporter type="pdf" target="tbl" fileName="cars" options="#{customizedDocumentsView.pdfOpt}"/>
This solution using PF showcase produces following result
Suggestion for extending this solution:
Primefaces exporter uses iText ver 2.1.7. with old but still powerful API. For example, in ExporterOptions in step 1. you can add
public int[] getColumnWidths();
to set absolute column widths or you can set any other option driven by your project requirements.
来源:https://stackoverflow.com/questions/32743148/primefaces-dataexporter-set-table-columns-width