如何将报告导出为 PDF/A-1a、PDF/A-1b?
Posted
技术标签:
【中文标题】如何将报告导出为 PDF/A-1a、PDF/A-1b?【英文标题】:How can I export report to PDF/A-1a, PDF/A-1b? 【发布时间】:2016-07-18 07:11:15 【问题描述】:在 jasper-report 中生成 PDF/A 包含许多陷阱,并且在某些版本的 jasper-report 中不受支持。这就是为什么我决定通过这个 Question-Answer 帖子,指出将带有图表的简单报告导出为 PDF/A 所需的步骤和库版本
样本数据 (usersRep.csv)
+----------------+--------+
| User | Rep |
+----------------+--------+
| Jon Skeet | 854503 |
| Darin Dimitrov | 652133 |
| BalusC | 639753 |
| Hans Passant | 616871 |
| Me | 5640 |
+----------------+--------+
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 splitType="Stretch">
<staticText>
<reportElement x="0" y="0" 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" 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 splitType="Stretch">
<textField>
<reportElement x="0" y="0" 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[$FUser]]></textFieldExpression>
</textField>
<textField>
<reportElement x="100" y="0" 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[$FRep]]></textFieldExpression>
</textField>
</band>
</detail>
<pageFooter>
<band >
<pieChart>
<chart isShowLegend="false">
<reportElement x="225" y="-670" uuid="23bd26a6-04a4-406f-8a1a-5e1b260cb75d"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend/>
</chart>
<pieDataset>
<keyExpression><![CDATA[$FUser]]></keyExpression>
<valueExpression><![CDATA[$FRep]]></valueExpression>
</pieDataset>
<piePlot>
<plot/>
<itemLabel/>
</piePlot>
</pieChart>
</band>
</pageFooter>
</jasperReport>
要导出为 PDF 的 Java 代码 (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();
这会将报告导出为 pdf,我需要做什么来生成 PDF/A-1a?
【问题讨论】:
【参考方案1】:JasperReports 库 4.1.2.3 或更高版本 is needed(在 6.0.0 中已停止支持,请参阅末尾的 NullPointerException
)。
这些步骤是生成 PDF/A 所需要的,它们可以通过 java 代码或将 jrxml property
设置为根标签(jasper-server 支持)来实现。我将同时展示这两种方法,但只需要一种方法。
#设置 PDF/A 一致性
java
configuration.setPdfaConformance(PdfaConformanceEnum.PDFA_1A); // or PdfaConformanceEnum.PDFA_1B
jrxml
<property name="net.sf.jasperreports.export.pdfa.conformance" value="pdfa1a" />
#设置ICC Profile
避免
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" />
#嵌入报告中使用的所有字体,使用font-extensions
如果还是有错误
com.lowagie.text.pdf.PdfXConformanceException: All the fonts must be embedded. This one isn't: Helvetica
在 jrxml 中包含一个默认样式,表示 fontName
包含在字体扩展中,示例
<style name="default" isDefault="true" fontName="DejaVu Sans"/>
#删除透明对象和图层(可选内容组)它们是not allowed
避免
PdfXConformanceException: Transparency is not allowed
例如,图表元素必须是Opaque
,为了避免标签透明,您可以实现JRChartCustomizer
public class NoTransparencyCustomizer implements JRChartCustomizer
@Override
public void customize(JFreeChart chart, JRChart jrchart)
PiePlot plot = (PiePlot) chart.getPlot();
plot.setLabelShadowPaint(Color.GRAY);
#Set 标记和标记语言(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"/>
#结果
这是实现上述的结果,将fontName
切换到DejaVu Sans
并使用捆绑的jasperreports-fonts.jar
作为字体扩展。它已在pdf-tools 上成功验证了 PDF/A-1a 和 PDF/A-1b
不适合我
XMP 属性与文档信息不同步
Validating file "reputation.pdf" for conformance level pdfa-1a
dc:description/*[0] :: Missing language qualifier.
dc:title/*[0] :: Missing language qualifier.
The XMP property 'dc:title' is not synchronized with the document information entry 'Title'.
The XMP property 'dc:description' is not synchronized with the document information entry 'Subject'.
当您在配置中设置元数据标题或主题时,此错误来自使用较旧的 jasper-reports 库
configuration.setMetadataTitle("Title");
configuration.setMetadataSubject("Subject");
解决方案是删除这些或将 jasper-reports 更新到版本 6.2.0 或更高版本,请参阅PDF/A_1A XMP Metadata validation fails if title and/or subject are set 了解更多信息
停止支持
在 jasper 报告版本 6.0.0 中,总是抛出 NullPointerException at com.itextpdf.text.pdf.internal.PdfA1Checker.checkPdfObject
。这已在 6.0.4 及更高版本中解决,请参阅 Jasper report tracker。
【讨论】:
以上是关于如何将报告导出为 PDF/A-1a、PDF/A-1b?的主要内容,如果未能解决你的问题,请参考以下文章
JasperReports 服务器:如何使用 url 将报告导出为 html 文件