我的任务是使用TCPDF / FPDI创建一个PHP工具,它可以获取现有PDF并在添加证书时将它们转换为PDF / A标准。
遗憾的是,所有生成的PDF都不符合PDF / A标准。我还尝试生成一个随机测试文档,如https://tcpdf.org/examples/example_065/所示,但该文档也不符合。
这是我的代码:
public static function convertPdf($path)
{
$pdf = new \FPDI(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false, true);
$pagecount = $pdf->setSourceFile(ROOT . $path);
for ($i = 1; $i <= $pagecount; $i++) {
$tpl = $pdf->importPage($i);
$size = $pdf->getTemplateSize($tpl);
$orientation = $size['h'] > $size['w'] ? 'P':'L';
$pdf->AddPage($orientation);
$pdf->useTemplate($tpl, null, null, $size['w'], $size['h'], true);
}
$pdf->SetCreator("Creator");
$pdf->SetAuthor('Nicola Asuni');
$pdf->SetTitle('My PDFA example');
$pdf->SetSubject('TCPDF Tutorial');
$certificatePath = 'file://' . ROOT . '/libs/TCPDF-master/examples/data/cert/tcpdf.crt';
// set additional information
$info = array(
'Name' => 'TCPDF',
'Location' => 'Office',
'Reason' => 'Testing TCPDF',
'ContactInfo' => 'http://www.tcpdf.org',
);
$pdf->setSignature($certificatePath, $certificatePath, 'tcpdfdemo', '', 2, $info);
$pdf->addEmptySignatureAppearance(0, 0, 0, 0);
$pdf->Output('example_065.pdf', 'I');
}
我使用这个https://www.pdf-online.com/osa/validate.aspx来验证我的PDF。它生成此输出:
合规性pdfa-1b结果文档不符合PDF / A.详细信息验证文件“testerrrrrr.pdf”的一致性级别pdfa-1b EOF标记后面有数据。 pdfaExtension:schemas / [0] ::在值类型'Schema'中缺少必填字段'property'。 pdfaExtension:schemas / [0] ::在值类型'Schema'中缺少必填字段'valueType'。 pdfaExtension:schemas / [1] ::在值类型'Schema'中缺少必需字段'valueType'。 pdfaExtension:schemas / [2] ::在值类型'Schema'中缺少必填字段'valueType'。外观字典不包含条目。密钥S具有禁止的透明度值。该文件不符合要求的标准。文件格式(标题,尾部,对象,外部参照,流)已损坏。该文件包含透明度。该文档包含具有暧昧或没有适当外观的注释或表单字段。文档的元数据丢失或不一致或损坏。完成。
通常:如果通过FPDI导入的文档不符合PDF / A(例如透明),则结果永远不会成功验证。仅通过TCPDF设置一些PDF / A标志不会使导入的页面与PDF / A一致。
TCPDF伪造签名外观,因为外观被写入页面内容流,而真实外观为空(鉴于“外观字典不包含条目”。)。
应该在TCPDF代码中添加缺少的属性(其他“验证器”不会抱怨它们)。
在我的情况下(TCPDF v.6.2.26),问题位于第9583行的tcpdf.php文件中:
$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:schema>Adobe PDF Schema</pdfaSchema:schema>'."\n";
$xmp .= "\t\t\t\t\t".'</rdf:li>'."\n";
$xmp .= "\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
在“Adobe PDF架构”之后,缺少该属性的声明。我解决了在pdfaSchema声明和li闭包标记之间添加以下代码:
$xmp .= "\t\t\t\t\t\t".'<pdfaSchema:property>'."\n";
$xmp .= "\t\t\t\t\t\t\t".'<rdf:Seq>'."\n";
$xmp .= "\t\t\t\t\t\t\t\t".'<rdf:li rdf:parseType="Resource">'."\n";
$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:category>internal</pdfaProperty:category>'."\n";
$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:description>A name object indicating whether the document has been modified to include trapping information</pdfaProperty:description>'."\n";
$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:name>Trapped</pdfaProperty:name>'."\n";
$xmp .= "\t\t\t\t\t\t\t\t\t".'<pdfaProperty:valueType>Text</pdfaProperty:valueType>'."\n";
$xmp .= "\t\t\t\t\t\t\t\t".'</rdf:li>'."\n";
$xmp .= "\t\t\t\t\t\t\t".'</rdf:Seq>'."\n";
$xmp .= "\t\t\t\t\t\t".'</pdfaSchema:property>'."\n";