Samples Overview
Conversion | ZUGFeRD | Signing | In Memory
Conversion
Convert PDF document to PDF/A and do a post-validation
Define which conversion should yield a conversion error, e.g. removing an action or converting a signed document. Then convert a PDF document to PDF/A and create a log file with a detailed description of the pre-analysis and post-validation. Throw a conversion error according to the previously defined rules.
// Create the converter
using (Pdf2Pdf converter = new Pdf2Pdf())
{
converter.Compliance = PDFCompliance.ePDFA2b;
converter.ReportSummary = true;
// The ConversionErrorMask property defines what is crucial to your process and
// should lead to a conversion error.
converter.ConversionErrorMask = (int)PDFConversionError.ePDFConversionErrorVisualDiff +
(int)PDFConversionError.ePDFConversionErrorActionRemoved +
(int)PDFConversionError.ePDFConversionErrorCorrupt +
(int)PDFConversionError.ePDFConversionErrorDocSigned +
(int)PDFConversionError.ePDFConversionErrorEFRemoved +
(int)PDFConversionError.ePDFConversionErrorFontSubst +
(int)PDFConversionError.ePDFConversionErrorStructureRemoved;
// Convert input file to PDF/A
if (!converter.Convert(inputPath, "", outputPath, Path.ChangeExtension(outputPath, null) + "-log.txt"))
{
if (converter.ErrorCode == PDFErrorCode.PDF_E_POSTANALYSIS)
{
// A post analysis error indicates that the output file is not PDF/A.
// A detailed description why the post analysis failed can be found in the log file.
throw new Exception(String.Format("The output file {0} is not PDF/A compliant. {1} " +
"(ErrorCode: 0x{2:x}).", outputPath, converter.ErrorMessage, converter.ErrorCode));
}
else if (converter.ErrorCode == PDFErrorCode.PDF_E_CONVERSION)
{
Array errors = Enum.GetValues(typeof(PDFConversionError));
// Print all conversion errors that occurred during conversion
Console.WriteLine("File converted to PDF/A, but the following " +
"conversion errors occurred:");
foreach (PDFConversionError err in errors)
{
if (((int)err & converter.ConversionErrors) != 0)
Console.WriteLine("- " + err.ToString());
}
// Decide if the errors are acceptable
Console.WriteLine(Environment.NewLine + "Please review the output file and confirm " +
"whether it is acceptable: [y/n] ");
if (Console.ReadLine().ToLower() != "y")
throw new Exception("The conversion result was rejected due to conversion errors.");
}
else
throw new Exception(String.Format("Input file {0} could not be converted to PDF/A. " +
"{1} (ErrorCode: 0x{2:x}).", inputPath, converter.ErrorMessage, converter.ErrorCode));
}
}
// Create the converter
converter = new Pdf2PdfAPI();
converter.setCompliance(NativeLibrary.COMPLIANCE.ePDFA2b);
converter.setReportSummary(true);
// The ConversionErrorMask property defines what is crucial to your process and
// should lead to a conversion error.
converter.setConversionErrorMask((int)NativeLibrary.CONVERSIONERROR.ePDFConversionErrorVisualDiff +
(int)NativeLibrary.CONVERSIONERROR.ePDFConversionErrorActionRemoved +
(int)NativeLibrary.CONVERSIONERROR.ePDFConversionErrorColorants +
(int)NativeLibrary.CONVERSIONERROR.ePDFConversionErrorCorrupt +
(int)NativeLibrary.CONVERSIONERROR.ePDFConversionErrorDocSigned +
(int)NativeLibrary.CONVERSIONERROR.ePDFConversionErrorEFRemoved +
(int)NativeLibrary.CONVERSIONERROR.ePDFConversionErrorFontSubst +
(int)NativeLibrary.CONVERSIONERROR.ePDFConversionErrorStructureRemoved);
// Convert input file to PDF/A
if (!converter.convert(inputPath, "", outputPath, outputPath.replace(".pdf", "") + "-log.txt"))
{
if (converter.getErrorCode() == NativeLibrary.ERRORCODE.PDF_E_POSTANALYSIS)
{
// A post analysis error indicates that the output file is not PDF/A.
// A detailed description why the post analysis failed can be found in the log file.
throw new IOException(String.format("The output file %s is not PDF/A compliant. " +
"%s (ErrorCode: 0x%08x).", outputPath, converter.getErrorMessage(),
converter.getErrorCode()));
}
else if (converter.getErrorCode() == NativeLibrary.ERRORCODE.PDF_E_CONVERSION)
{
int errors = (converter.getConversionErrorMask() & converter.getConversionErrors());
// Print all conversion errors that occurred during conversion
System.out.println("File converted to PDF/A, but the following " +
"conversion errors occurred (see NativeLibrary.CONVERSIONERROR):");
for (int i = 1; i <= errors; i = 2*i)
{
if ((i & errors) != 0)
System.out.println(String.format("- 0x%05x", i));
}
// Decide if the errors are acceptable
System.out.println("Please review the output file and confirm whether " +
"it is acceptable: [y/n]");
while((char) System.in.read() != 'y')
throw new IOException("The conversion result was rejected due to conversion errors.");
}
else
throw new IOException(String.format("Input file %s could not be converted to PDF/A. " +
"%s (ErrorCode: 0x%08x).", outputPath, converter.getErrorMessage(),
converter.getErrorCode()));
}
// Create the converter
pConverter = Pdf2PdfCreateObject();
Pdf2PdfSetCompliance(pConverter, ePDFA2b);
Pdf2PdfSetReportSummary(pConverter, 1);
// The ConversionErrorMask property defines what is crucial to your process and
// should lead to a conversion error
Pdf2PdfSetConversionErrorMask(pConverter, (int)ePDFConversionErrorVisualDiff + (int)ePDFConversionErrorActionRemoved +
(int)ePDFConversionErrorCorrupt + (int)ePDFConversionErrorDocSigned + (int)ePDFConversionErrorEFRemoved +
(int)ePDFConversionErrorFontSubst + (int)ePDFConversionErrorStructureRemoved);
// Get logfile name
_tcscpy(szCopyFile, szOutputPath);
szLogFileName = _tcstok(szCopyFile, _T("."));
_tcscat(szLogFileName, _T("-log.txt"));
// Convert input file to PDF/A
if (!Pdf2PdfConvert(pConverter, szInputPath, _T(""), szOutputPath, szLogFileName))
{
if (Pdf2PdfGetErrorCode(pConverter) == PDF_E_POSTANALYSIS)
{
// A post analysis error indicates that the output file is not PDF/A.
// A detailed description why the post analysis failed can be found in the log file.
_tprintf(_T("The output file %s is not PDF/A compliant. %s (ErrorCode: 0x%08x).\n"), szOutputPath, Pdf2PdfGetErrorMessage(pConverter), Pdf2PdfGetErrorCode(pConverter));
iReturnValue = 1;
goto cleanup;
}
else if (Pdf2PdfGetErrorCode(pConverter) == PDF_E_CONVERSION)
{
int errors = Pdf2PdfGetConversionErrors(pConverter);
// Print all conversion errors that occurred during conversion
_tprintf(_T("File converted to PDF/A, but the following conversion errors occurred (see TPDFConversionError):\n"));
for (int i = 1; i <= errors; i = 2 * i)
{
if ((i & errors) != 0)
{
_tprintf(_T("- 0x%05x\n"), i);
}
}
// Decide if the errors are acceptable
_tprintf(_T("\nPlease review the output file and confirm whether it is acceptable: [y/n] \n"));
scanf("%s", str);
if (_tcscmp(str, _T("y")) != 0)
{
_tprintf(_T("The conversion result was rejected due to conversion errors.\n"));
iReturnValue = 1;
goto cleanup;
}
}
else
{
_tprintf(_T("Input file %s could not be converted to PDF/A. %s (ErrorCode: 0x%08x).\n"), szInputPath, Pdf2PdfGetErrorMessage(pConverter), Pdf2PdfGetErrorCode(pConverter));
iReturnValue = 1;
goto cleanup;
}
}
Convert PDF document to PDF/A
Convert a PDF document to a specific PDF/A compliance level such as PDF/A-2u. Allow for automatic downgrade, e.g. to PDF/A-2b, if the input file cannot be converted otherwise.
// Create the converter
using (Pdf2Pdf converter = new Pdf2Pdf())
{
// Set compliance level
converter.Compliance = compliance;
converter.AllowDowngrade = true;
// Convert to PDF/A
if (!converter.Convert(inputPath, "", outputPath, ""))
throw new Exception(String.Format("Input file {0} could not be converted. " +
"{1} (ErrorCode: 0x{2:x}).", inputPath, converter.ErrorMessage, converter.ErrorCode));
}
// Create the converter
converter = new Pdf2PdfAPI();
// Set compliance level
converter.setCompliance(compliance);
converter.setAllowDowngrade(true);
// Convert to PDF/A
if (!converter.convert(inputPath, "", outputPath, ""))
throw new Exception(String.format("Input file %s could not be converted. %s " +
"(ErrorCode: 0x%08x).", inputPath, converter.getErrorMessage(), converter.getErrorCode()));
// Create the converter
pConverter = Pdf2PdfCreateObject();
// Set compliance level
Pdf2PdfSetCompliance(pConverter, eCompliance);
Pdf2PdfSetAllowDowngrade(pConverter, 1);
// Convert to PDF/A
if (!Pdf2PdfConvert(pConverter, szInputPath, _T(""), szOutputPath, _T("")))
{
_tprintf(_T("Input file %s could not be converted. %s (ErrorCode: 0x%08x).\n"), szInputPath, Pdf2PdfGetErrorMessage(pConverter), Pdf2PdfGetErrorCode(pConverter));
iReturnValue = 1;
}
ZUGFeRD
Create a ZUGFeRD invoice
Convert a PDF document to PDF/A-3 and embed conforming XML data to create a ZUGFeRD compliant invoice.
// Create the converter
using (Pdf2Pdf converter = new Pdf2Pdf())
{
// A ZUGFeRD invoice has to be PDF/A-3 compliant
converter.Compliance = PDFCompliance.ePDFA3u;
converter.AllowDowngrade = true;
// Add ZUGFeRD invoice
if (!converter.AddInvoiceXml(PDFInvoiceType.ePDFInvoiceZugferd, invoicePath, null))
throw new Exception(String.Format("ZUGFeRD invoice {0} could not be added. " +
"{1} (ErrorCode: 0x{2:x}).", invoicePath, converter.ErrorMessage, converter.ErrorCode));
// Convert PDF to PDF/A
if (!converter.Convert(inputPath, "", outputPath, ""))
throw new Exception(String.Format("Input file {0} could not be converted. " +
"{1} (ErrorCode: 0x{2:x}).", inputPath, converter.ErrorMessage, converter.ErrorCode));
}
// Create the converter
converter = new Pdf2PdfAPI();
// A ZUGFeRD invoice has to be PDF/A-3 compliant
converter.setCompliance(NativeLibrary.COMPLIANCE.ePDFA3u);
converter.setAllowDowngrade(true);
// Add ZUGFeRD invoice
if (!converter.addInvoiceXml(NativeLibrary.PDFINVOICETYPE.ePDFInvoiceZugferd, invoicePath, null))
throw new IOException(String.format("ZUGFeRD invoice %s could not be added. " +
"%s (ErrorCode: 0x%08x).", invoicePath, converter.getErrorMessage(),
converter.getErrorCode()));
// Convert PDF to PDF/A
if (!converter.convert(inputPath, "", outputPath, ""))
throw new IOException(String.format("Input file %s could not be converted. %s " +
"(ErrorCode: 0x%08x).", inputPath, converter.getErrorMessage(), converter.getErrorCode()));
// Create the converter
pConverter = Pdf2PdfCreateObject();
// A ZUGFeRD invoice has to be PDF/A-3 compliant
Pdf2PdfSetCompliance(pConverter, ePDFA3u);
Pdf2PdfSetAllowDowngrade(pConverter, 1);
// Add ZUGFeRD invoice
if (!Pdf2PdfAddInvoiceXml(pConverter, ePDFInvoiceZugferd, szInvoicePath, NULL))
{
_tprintf(_T("ZUGFeRD invoice %s could not be added. %s (ErrorCode: 0x%08x).\n"), szInvoicePath, Pdf2PdfGetErrorMessage(pConverter), Pdf2PdfGetErrorCode(pConverter));
iReturnValue = 1;
goto cleanup;
}
// Convert PDF to PDF/A
if (!Pdf2PdfConvert(pConverter, szInputPath, _T(""), szOutputPath, _T("")))
{
_tprintf(_T("Input file %s could not be converted. %s (ErrorCode: 0x%08x).\n"), szInputPath, Pdf2PdfGetErrorMessage(pConverter), Pdf2PdfGetErrorCode(pConverter));
iReturnValue = 1;
}
Signing
Convert PDF document to PDF/A and add a signature
Prepare PDF documents for long-term archiving. For that purpose, convert a PDF to an electronically signed PDF/A document. The signature is created using a certificate that contains a private key. Use the Windows Cryptographic Provider to access the certificate via its common name (CN) and to get necessary cryptographic algorithms.
// Create the converter
using (Pdf2Pdf converter = new Pdf2Pdf())
{
// Set compliance
converter.Compliance = PDFCompliance.ePDFA2b;
// Begin session with Windows cryptographic provider
if (!converter.BeginSession(""))
throw new Exception(String.Format("Unable to connect to Windows cryptographic provider. " +
"{0} (ErrorCode: 0x{1:x}).", converter.ErrorMessage, converter.ErrorCode));
// Create signature object
using (Signature signature = new Signature())
{
signature.Name = certificate;
converter.AddSignature(signature);
// Create PDF/A and sign it
if (!converter.Convert(inputPath, "", outputPath, ""))
throw new Exception(String.Format("Input file {0} could not be converted. {1} " +
"(ErrorCode: 0x{2:x}).", inputPath, converter.ErrorMessage, converter.ErrorCode));
}
// Cleanup
converter.EndSession();
Pdf2Pdf.Terminate();
}
// Create the converter
converter = new Pdf2PdfAPI();
// Set compliance
converter.setCompliance(NativeLibrary.COMPLIANCE.ePDFA2b);
// Begin session with Windows cryptographic provider
if (!converter.beginSession(""))
throw new Exception(String.format("Unable to connect to Windows cryptographic provider. " +
"%s (ErrorCode: 0x%08x).", converter.getErrorMessage(), converter.getErrorCode()));
// Create signature object
signature = new Signature();
signature.setName(certificate);
converter.addSignature(signature);
// Create PDF/A and sign it
if (!converter.convert(inputPath, "", outputPath, ""))
throw new IOException(String.format("Input file %s could not be converted. %s " +
"(ErrorCode: 0x%08x)", inputPath, converter.getErrorMessage(), converter.getErrorCode()));
// Clean up
converter.endSession();
// Create the converter
pConverter = Pdf2PdfCreateObject();
// Set compliance
Pdf2PdfSetCompliance(pConverter, ePDFA2b);
// Begin session with Windows cryptographic provider
if (!Pdf2PdfBeginSession(pConverter, ""))
{
_tprintf(_T("Unable to connect to Windows cryptographic provider. %s (ErrorCode: 0x%08x).\n"), Pdf2PdfGetErrorMessage(pConverter), Pdf2PdfGetErrorCode(pConverter));
iReturnValue = 1;
goto cleanup;
}
// Create signature object
pSignature = Pdf2PdfSignatureCreateObject();
Pdf2PdfSignatureSetName(pSignature, szCertificate);
Pdf2PdfAddSignature(pConverter, pSignature);
Pdf2PdfSignatureDestroyObject(pSignature);
// Create PDF/A and sign it
if (!Pdf2PdfConvert(pConverter, szInputPath, _T(""), szOutputPath, _T("")))
{
_tprintf(_T("Input file %s could not be converted. %s (ErrorCode: 0x%08x).\n"), szInputPath, Pdf2PdfGetErrorMessage(pConverter), Pdf2PdfGetErrorCode(pConverter));
iReturnValue = 1;
}
In Memory
Convert PDF document to PDF/A in memory
Read a PDF from a byte stream and convert it to PDF/A as byte stream. For demonstration purpose, the PDF byte stream is created from file and the PDF/A byte stream is written back to a file.
// Create the converter
using (Pdf2Pdf converter = new Pdf2Pdf())
{
// Convert input PDF byte array to output PDF/A byte array, get log file as byte array
if (!converter.ConvertMem(inputBuffer, "", out outputBuffer, out logBuffer))
throw new Exception(String.Format("File could not be converted to PDF/A. " +
"{0} (ErrorCode: 0x{1:x}).", converter.ErrorMessage, converter.ErrorCode));
}
// Write bytes to output file
File.WriteAllBytes(outputPath, outputBuffer);
// Write bytes to log file
File.WriteAllBytes(logPath, logBuffer);
// Create the converter
converter = new Pdf2PdfAPI();
// Convert input PDF byte array to output PDF/A byte array, get log file as byte array
if (!converter.convertMem2(inputBuffer, ""))
throw new IOException(String.format("PDF/A could not be created. %s (ErrorCode: 0x%08x).",
converter.getErrorMessage(), converter.getErrorCode()));
// Get PDF as buffer
byte[] outputBuffer = converter.getPDF();
if (outputBuffer == null)
throw new IOException(String.format("Output file %s cannot be converted as a byte array. %s " +
"(ErrorCode: 0x%08x).", outputPath, converter.getErrorMessage(), converter.getErrorCode()));
// Get output log as Buffer
byte[] logBuffer = converter.getLog();
// Write bytes to output file
Files.write(Paths.get(outputPath), outputBuffer);
// Write bytes to log file
Files.write(Paths.get(logPath), logBuffer);
// Create the converter
pConverter = Pdf2PdfCreateObject();
// Convert input PDF byte array to output PDF/A byte array, get log file as byte array
if (!Pdf2PdfConvertMem(pConverter, pInputBuffer, nLength, _T(""), &pOutputBuffer, &nOutLength, &pLogBuffer, &nLogLength))
{
_tprintf(_T("File could not be converted to PDF/A. %s (ErrorCode: 0x%08x).\n"), Pdf2PdfGetErrorMessage(pConverter), Pdf2PdfGetErrorCode(pConverter));
iReturnValue = 1;
goto cleanup;
}
// Write bytes to output file
pData = _tfopen(szOutputPath, _T("wb"));
fwrite(pOutputBuffer, 1, nOutLength, pData);
fclose(pData);
// Write bytes to log file
pLog = _tfopen(szLogPath, _T("wb"));
fwrite(pLogBuffer, 1, nLogLength, pLog);
fclose(pLog);