How can I export report to PDF/A-1a, PDF/A-1b?

白昼怎懂夜的黑 提交于 2019-11-26 11:24:07

问题


Generating PDF/A in jasper-report, contains numerous pitfalls and is not supported in some versions of jasper-report. This is why I have decided to pass this Question-Answer post, indicating the steps and library version necessary to export a simple report with a graph to PDF/A

Sample data (usersRep.csv)

+----------------+--------+
|      User      |  Rep   |
+----------------+--------+
| Jon Skeet      | 854503 |
| Darin Dimitrov | 652133 |
| BalusC         | 639753 |
| Hans Passant   | 616871 |
| Me             |   5640 |
+----------------+--------+

Sample jrxml (reputation.jrxml)

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<jasperReport xmlns=\"http://jasperreports.sourceforge.net/jasperreports\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd\" name=\"reputation\" pageWidth=\"595\" pageHeight=\"842\" columnWidth=\"555\" leftMargin=\"20\" rightMargin=\"20\" topMargin=\"20\" bottomMargin=\"20\" uuid=\"a88bd694-4f90-41fc-84d0-002b90b2d73e\">
    <queryString>
        <![CDATA[]]>
    </queryString>
    <field name=\"User\" class=\"java.lang.String\"/>
    <field name=\"Rep\" class=\"java.lang.Long\"/>
    <columnHeader>
        <band height=\"20\" splitType=\"Stretch\">
            <staticText>
                <reportElement x=\"0\" y=\"0\" width=\"100\" height=\"20\" uuid=\"9e7b5f50-5795-4c95-a122-f14f2e3f9366\"/>
                <box leftPadding=\"3\" bottomPadding=\"0\" rightPadding=\"3\">
                    <pen lineWidth=\"0.25\"/>
                    <topPen lineWidth=\"0.25\"/>
                    <leftPen lineWidth=\"0.25\"/>
                    <bottomPen lineWidth=\"0.5\" lineStyle=\"Double\"/>
                    <rightPen lineWidth=\"0.25\"/>
                </box>
                <textElement verticalAlignment=\"Middle\">
                    <font fontName=\"SansSerif\" isBold=\"true\"/>
                </textElement>
                <text><![CDATA[User]]></text>
            </staticText>
            <staticText>
                <reportElement x=\"100\" y=\"0\" width=\"100\" height=\"20\" uuid=\"4a6f0a2a-d9b5-4e74-a9e8-0f965336f2bf\"/>
                <box leftPadding=\"3\" bottomPadding=\"0\" rightPadding=\"3\">
                    <pen lineWidth=\"0.25\"/>
                    <topPen lineWidth=\"0.25\"/>
                    <leftPen lineWidth=\"0.25\"/>
                    <bottomPen lineWidth=\"0.5\" lineStyle=\"Double\"/>
                    <rightPen lineWidth=\"0.25\"/>
                </box>
                <textElement textAlignment=\"Right\" verticalAlignment=\"Middle\">
                    <font fontName=\"SansSerif\" isBold=\"true\"/>
                </textElement>
                <text><![CDATA[Reputation]]></text>
            </staticText>
        </band>
    </columnHeader>
    <detail>
        <band height=\"20\" splitType=\"Stretch\">
            <textField>
                <reportElement x=\"0\" y=\"0\" width=\"100\" height=\"20\" uuid=\"8ff583b9-88dc-4726-85e1-16d79de78095\"/>
                <box leftPadding=\"3\" bottomPadding=\"0\" rightPadding=\"3\">
                    <pen lineWidth=\"0.25\"/>
                    <topPen lineWidth=\"0.25\"/>
                    <leftPen lineWidth=\"0.25\"/>
                    <bottomPen lineWidth=\"0.25\"/>
                    <rightPen lineWidth=\"0.25\"/>
                </box>
                <textElement verticalAlignment=\"Middle\">
                    <font fontName=\"SansSerif\"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{User}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x=\"100\" y=\"0\" width=\"100\" height=\"20\" uuid=\"ebd33b2f-7297-41c2-9dc7-78ff472890c4\"/>
                <box leftPadding=\"3\" bottomPadding=\"0\" rightPadding=\"3\">
                    <pen lineWidth=\"0.25\"/>
                    <topPen lineWidth=\"0.25\"/>
                    <leftPen lineWidth=\"0.25\"/>
                    <bottomPen lineWidth=\"0.25\"/>
                    <rightPen lineWidth=\"0.25\"/>
                </box>
                <textElement textAlignment=\"Right\" verticalAlignment=\"Middle\">
                    <font fontName=\"SansSerif\"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{Rep}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
    <pageFooter>
        <band height=\"140\">
            <pieChart>
                <chart isShowLegend=\"false\">
                    <reportElement x=\"225\" y=\"-670\" width=\"320\" height=\"140\" uuid=\"23bd26a6-04a4-406f-8a1a-5e1b260cb75d\"/>
                    <chartTitle/>
                    <chartSubtitle/>
                    <chartLegend/>
                </chart>
                <pieDataset>
                    <keyExpression><![CDATA[$F{User}]]></keyExpression>
                    <valueExpression><![CDATA[$F{Rep}]]></valueExpression>
                </pieDataset>
                <piePlot>
                    <plot/>
                    <itemLabel/>
                </piePlot>
            </pieChart>
        </band>
    </pageFooter>
</jasperReport>

Java code to export to PDF (reputation.pdf)

JasperReport report = JasperCompileManager.compileReport(\"reputation.jrxml\");
JRCsvDataSource datasource = new JRCsvDataSource(\"usersRep.csv\");
datasource.setFieldDelimiter(\';\');
datasource.setUseFirstRowAsHeader(true);

JasperPrint jasperPrint = JasperFillManager.fillReport(report, new HashMap<String, Object>(),datasource);

JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(\"reputation.pdf\"));
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
configuration.setMetadataAuthor(\"Me and only me\");
exporter.setConfiguration(configuration);
exporter.exportReport();

This export the report to a pdf, what do I need to do to generate a PDF/A-1a?


回答1:


JasperReports Library 4.1.2.3 or higher is needed (with discontinued support in 6.0.0 see NullPointerException at the end).

These steps are need to generate a PDF/A, they can be achieved both by java code or by setting jrxml property to root tag (jasper-server support). I will show both but only one method is necessary.

Set PDF/A Conformance

java

configuration.setPdfaConformance(PdfaConformanceEnum.PDFA_1A); // or PdfaConformanceEnum.PDFA_1B

jrxml

<property name="net.sf.jasperreports.export.pdfa.conformance" value="pdfa1a" />

Set ICC Profile

to avoid JRPdfaIccProfileNotFoundException: The ICC profile is not available to the JVM

java

configuration.setIccProfilePath("srgb.icc");

jrxml

<property name="net.sf.jasperreports.export.pdfa.icc.profile.path" value="srgb.icc" />

Embed all font used in reports, using font-extensions

If you still have error

com.lowagie.text.pdf.PdfXConformanceException: All the fonts must be embedded. This one isn't: Helvetica

include a default style in the jrxml indicating fontName that is included in font extension, example

<style name="default" isDefault="true" fontName="DejaVu Sans"/>

Remove transparent objects and layers (Optional Content Groups) they are not allowed

to avoid PdfXConformanceException: Transparency is not allowed

In example the chart element must be Opaque and to avoid transparency on the labels you can implement a JRChartCustomizer

public class NoTransparencyCustomizer implements JRChartCustomizer{
    @Override
    public void customize(JFreeChart chart, JRChart jrchart) {
        PiePlot plot = (PiePlot) chart.getPlot();
        plot.setLabelShadowPaint(Color.GRAY);       
    }
}

Set Tagged and tag language (unnecessary for PDF/A-1b)

java

configuration.setTagged(true);
configuration.setTagLanguage("en-us");

jrxml

<property name="net.sf.jasperreports.export.pdf.tagged" value="true" />
<property name="net.sf.jasperreports.export.pdf.tag.language" value="en-us"/>

Result

This is the result implementing the above, switching fontName to DejaVu Sans and using the bundled jasperreports-fonts.jar as font-extension. It has been validated successfully on pdf-tools for both PDF/A-1a and PDF/A-1b

No piece of the cake for me

Discontinued support In jasper report version 6.0.0 a NullPointerException at com.itextpdf.text.pdf.internal.PdfA1Checker.checkPdfObject was always thrown. This has been solved in 6.0.4 and above see Jasper report tracker.



来源:https://stackoverflow.com/questions/36306170/how-can-i-export-report-to-pdf-a-1a-pdf-a-1b

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!