Skip to main content

Pdftools SDK code samples

Start using the Pdftools SDK library with code samples. Integrate advanced PDF manipulation, optimization, and validation tasks into your application in Java, .NET, C, and Python.

info

Select a code sample in a specific language and download it. The code samples illustrate how to integrate the SDK into your projects for specific use cases. Each code sample includes a README file that gives instructions on how to run the code sample to process one or multiple files.

tip

Do you miss a specific sample and want us to include it here? Let us know through the Contact page, and we’ll add it to our sample backlog.

Assembling documents

Merge PDFs

Download code sample
// Create output stream
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to create output file \"%s\" for writing.\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);
pAssembler = PdfToolsDocumentAssembly_DocumentAssembler_New(&outDesc, NULL, NULL);

for (int i = 1; i < argc - 1; i++)
{
szInPath = argv[i];
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"),
szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Append the content of the input documents to the output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
PdfToolsDocumentAssembly_DocumentAssembler_Append(pAssembler, pInDoc, NULL, NULL, NULL, NULL),
_T("Failed to append a page. (ErrorCode: 0x%08x).\n"), PdfTools_GetLastError());

PdfToolsPdf_Document_Close(pInDoc);
fclose(pInStream);
pInDoc = NULL;
pInStream = NULL;
}
// Merge input documents into an output document
pOutDoc = PdfToolsDocumentAssembly_DocumentAssembler_Assemble(pAssembler);

GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());
Download code sample
private static void Merge(IEnumerable<string> inPaths, string outPath)
{
// Create output stream
using var outStream = File.Create(outPath);
using var docAssembler = new PdfTools.DocumentAssembly.DocumentAssembler(outStream);

foreach (var inPath in inPaths)
{
using var inStream = File.OpenRead(inPath);
using var inDoc = PdfTools.Pdf.Document.Open(inStream);
// Append the content of the input documents to the output document
docAssembler.Append(inDoc);
}

// Merge input documents into an output document
docAssembler.Assemble();
}
Download code sample
    private static void merge(String[] inPaths, String outPath) throws Exception
{
try (
// Create output stream
FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
DocumentAssembler docAssembler = new DocumentAssembler(outStream)) {
for (String inPath : inPaths) {
try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr)) {
// Append the content of each input document to the output document
docAssembler.append(inDoc);
}
}
// Merge input documents into an output document
docAssembler.assemble();
}
}
Download code sample
def merge(input_paths: str, output_path: str):
# Create output stream
with io.FileIO(output_path, 'wb+') as output_stream:
with DocumentAssembler(output_stream, None, None) as assembler:

for input_path in input_paths:
with open(input_path, 'rb') as input_stream:
with Document.open(input_stream) as input_document:
# Append the content of the input documents to the output document
assembler.append(input_document)

# Merge input documents into an output document
assembler.assemble()
merge(input_paths, output_path)
Download code sample
Private Sub Merge(inPaths As IEnumerable(Of String), outPath As String)
' Create output stream
Using outStream = File.Create(outPath)
Using docAssembler = New PdfTools.DocumentAssembly.DocumentAssembler(outStream)

For Each inPath In inPaths
Using inStream = File.OpenRead(inPath)
Using inDoc = PdfTools.Pdf.Document.Open(inStream)
' Append the content of the input documents to the output document
docAssembler.Append(inDoc)
End Using
End Using
Next

' Merge input documents into an output document
docAssembler.Assemble()
End Using
End Using
End Sub

Split a PDF

Download code sample
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));

GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Split input document by generating one output document per page
int nPageCount = PdfToolsPdf_Document_GetPageCount(pInDoc);
TCHAR szPageFileName[256];
for (int i = 1; i <= nPageCount; i++)
{
CreateOutputFileName(szPageFileName, szOutPath, i);

// Create output stream for each page of the input document
pOutStream = _tfopen(szPageFileName, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the input file \"%s\" for reading.\n"),
szPageFileName);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Split pdf into pages
pAssembler = PdfToolsDocumentAssembly_DocumentAssembler_New(&outDesc, NULL, NULL);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
PdfToolsDocumentAssembly_DocumentAssembler_Append(pAssembler, pInDoc, &i, &i, NULL, NULL),
_T("Failed to append a page. (ErrorCode: 0x%08x).\n"), PdfTools_GetLastError());
pOutDoc = PdfToolsDocumentAssembly_DocumentAssembler_Assemble(pAssembler);
PdfToolsDocumentAssembly_DocumentAssembler_Close(pAssembler);

if (pOutDoc)
PdfToolsPdf_Document_Close(pOutDoc);
if (pOutStream)
fclose(pOutStream);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());
}
Download code sample
private static void Split(string inPath, string outPathPrefix)
{
// Open input document
using var inStream = File.OpenRead(inPath);
using var inDoc = PdfTools.Pdf.Document.Open(inStream);

// Split the input document page by page
for (int i = 1; i <= inDoc.PageCount; ++i)
{
using var outStream = File.Create(outPathPrefix + "_page_" + i + ".pdf");
using var docAssembler = new PdfTools.DocumentAssembly.DocumentAssembler(outStream);
docAssembler.Append(inDoc, i, i);
docAssembler.Assemble();
}
}
Download code sample
private static void split(String inPath, String outPathPrefix) throws Exception
{
try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr)) {
for (int i = 1; i <= inDoc.getPageCount(); ++i) {
try (
// Create output stream for each page of the input document
FileStream outStream = new FileStream(outPathPrefix + "_page_" + i + ".pdf", FileStream.Mode.READ_WRITE_NEW);
DocumentAssembler docAssembler = new DocumentAssembler(outStream)) {
docAssembler.append(inDoc, i, i);
docAssembler.assemble();
}
}
}
}
Download code sample
def split_pdf(input_file_path: str, output_file_path: str):
# Open input document
with open(input_file_path, 'rb') as input_stream:
with Document.open(input_stream) as input_document:
# Split the input document page by page
for i in range(1, input_document.page_count + 1):
current_out_file = construct_file_name(output_file_path, i)
with open(current_out_file, 'wb+') as output_stream:
with DocumentAssembler(output_stream, None, None) as assembler:
assembler.append(input_document, i, i)
assembler.assemble()
# Construct file name from input path and page number of input document
def construct_file_name(input_file: str, page_number: int):
# Split the directory and file name from the input path
directory, basename = os.path.split(input_file)

# Split the file base name and extension
base, extension = os.path.splitext(basename)

return os.path.join(directory, f"{base}_page_{page_number}{extension}")
split_pdf(input_path, output_path)
Download code sample
Private Sub Split(inPath As String, outPathPrefix As String)
' Open input document
Using inStream = File.OpenRead(inPath)
Using inDoc = PdfTools.Pdf.Document.Open(inStream)

' Split the input document page by page
For i As Integer = 1 To inDoc.PageCount
Using outStream = File.Create(outPathPrefix & "_page_" & i & ".pdf")
Using docAssembler = New PdfTools.DocumentAssembly.DocumentAssembler(outStream)
docAssembler.Append(inDoc, i, i)
docAssembler.Assemble()
End Using
End Using
Next
End Using
End Using
End Sub

Converting documents to PDF/A

Convert a PDF to PDF/A-2b if necessary

Download code sample
void EventListener(void* pContext, const char* szDataPart, const char* szMessage,
TPdfToolsPdfAConversion_EventSeverity iSeverity, TPdfToolsPdfAConversion_EventCategory iCategory,
TPdfToolsPdfAConversion_EventCode iCode, const char* szContext, int iPageNo)
{
// iSeverity is the event's suggested severity
// Optionally the suggested severity can be changed according to
// the requirements of your conversion process and, for example,
// the event's category (e.Category).

if (iSeverity > iEventsSeverity)
iEventsSeverity = iSeverity;

// Report conversion event
TCHAR cSeverity = iSeverity == ePdfToolsPdfAConversion_EventSeverity_Information ? 'I'
: ePdfToolsPdfAConversion_EventSeverity_Warning ? 'W'
: 'E';
if (iPageNo > 0)
_tprintf(_T("- %c %d: %s (%s on page %d)\n"), cSeverity, iCategory, szMessage, szContext, iPageNo);
else
_tprintf(_T("- %c %d: %s (%s)\n"), cSeverity, iCategory, szMessage, szContext);
}
void ConvertIfNotConforming(const TCHAR* szInPath, const TCHAR* szOutPath, TPdfToolsPdf_Conformance iConf)
{
TPdfToolsPdfAValidation_AnalysisOptions* pAOpt = NULL;
TPdfToolsPdfAValidation_Validator* pValidator = NULL;
TPdfToolsPdfAValidation_AnalysisResult* pARes = NULL;
TPdfToolsPdfAConversion_ConversionOptions* pConvOpt = NULL;
TPdfToolsPdfAConversion_Converter* pConv = NULL;
TPdfToolsPdf_Document* pOutDoc = NULL;
TPdfToolsPdf_Document* pInDoc = NULL;
FILE* pInStream = NULL;
FILE* pOutStream = NULL;

// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Failed to open document \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrBuf, PdfTools_GetLastError());

// Create validator to analyze PDF/A standard conformance of input document
pAOpt = PdfToolsPdfAValidation_AnalysisOptions_New();
PdfToolsPdfAValidation_AnalysisOptions_SetConformance(pAOpt, iConf);
pValidator = PdfToolsPdfAValidation_Validator_New();
pARes = PdfToolsPdfAValidation_Validator_Analyze(pValidator, pInDoc, pAOpt);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pARes, _T("Failed to analyze document. %s (ErrorCode: 0x%08x).\n"), szErrBuf,
PdfTools_GetLastError());

// Check if conversion to PDF/A is necessary
if (PdfToolsPdfAValidation_AnalysisResult_IsConforming(pARes))
{
printf("Document conforms to %s already.\n", PdfToolsPdf_Conformance_ToStringA(iConf));
goto cleanup;
}

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to create the output file \"%s\".\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Convert the input document to PDF/A using the converter object
// and its conversion event handler
pConvOpt = PdfToolsPdfAConversion_ConversionOptions_New();
pConv = PdfToolsPdfAConversion_Converter_New();
PdfToolsPdfAConversion_Converter_AddConversionEventHandlerA(
pConv, NULL, (TPdfToolsPdfAConversion_Converter_ConversionEventA)EventListener);
pOutDoc = PdfToolsPdfAConversion_Converter_Convert(pConv, pARes, pInDoc, &outDesc, pConvOpt, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Failed to convert document. %s (ErrorCode: 0x%08x).\n"), szErrBuf,
PdfTools_GetLastError());

// Check if critical conversion events occurred
switch (iEventsSeverity)
{
case ePdfToolsPdfAConversion_EventSeverity_Information:
{
TPdfToolsPdf_Conformance iOutConf;
PdfToolsPdf_Document_GetConformance(pOutDoc, &iOutConf);
printf("Successfully converted document to %s.\n", PdfToolsPdf_Conformance_ToStringA(iOutConf));
break;
}

case ePdfToolsPdfAConversion_EventSeverity_Warning:
{
TPdfToolsPdf_Conformance iOutConf;
PdfToolsPdf_Document_GetConformance(pOutDoc, &iOutConf);
printf("Warnings occurred during the conversion of document to %s.\n",
PdfToolsPdf_Conformance_ToStringA(iOutConf));
printf("Check the output file to decide if the result is acceptable.\n");
break;
}

case ePdfToolsPdfAConversion_EventSeverity_Error:
{
printf("Unable to convert document to %s because of critical conversion events.\n",
PdfToolsPdf_Conformance_ToStringA(iConf));
break;
}
}

cleanup:
PdfToolsPdf_Document_Close(pOutDoc);
PdfTools_Release(pConv);
PdfTools_Release(pConvOpt);
PdfTools_Release(pARes);
PdfTools_Release(pValidator);
PdfTools_Release(pAOpt);
PdfToolsPdf_Document_Close(pInDoc);
if (pInStream)
fclose(pInStream);
if (pOutStream)
fclose(pOutStream);
}
Download code sample
static void ConvertIfNotConforming(string inPath, string outPath, Conformance conformance)
{
// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create the Validator object, and use the Conformance object to create
// an AnalysisOptions object that controls the behavior of the Validator.
var validator = new Validator();
var analysisOptions = new AnalysisOptions() { Conformance = conformance };

// Run the analysis, and check the results.
// Only proceed if document is not conforming.
var analysisResult = validator.Analyze(inDoc, analysisOptions);
if (analysisResult.IsConforming)
{
Console.WriteLine($"Document conforms to {inDoc.Conformance} already.");
return;
}

// Create a converter object
var converter = new Converter();

// Add handler for conversion events
var eventsSeverity = EventSeverity.Information;
converter.ConversionEvent += (s, e) =>
{
// Get the event's suggested severity
var severity = e.Severity;

// Optionally the suggested severity can be changed according to
// the requirements of your conversion process and, for example,
// the event's category (e.Category).

if (severity > eventsSeverity)
eventsSeverity = severity;

// Report conversion event
Console.WriteLine("- {0} {1}: {2} ({3}{4})",
severity.ToString()[0], e.Category, e.Message, e.Context, e.PageNo > 0 ? " page " + e.PageNo : ""
);
};

// Create stream for output file
using var outStr = File.Create(outPath);

// Convert the input document to PDF/A using the converter object
// and its conversion event handler
using var outDoc = converter.Convert(analysisResult, inDoc, outStr);

// Check if critical conversion events occurred
switch (eventsSeverity)
{
case EventSeverity.Information:
Console.WriteLine($"Successfully converted document to {outDoc.Conformance}.");
break;

case EventSeverity.Warning:
Console.WriteLine($"Warnings occurred during the conversion of document to {outDoc.Conformance}.");
Console.WriteLine($"Check the output file to decide if the result is acceptable.");
break;

case EventSeverity.Error:
throw new Exception($"Unable to convert document to {conformance} because of critical conversion events.");
}
}
Download code sample
private static void convertIfNotConforming(String inPath, String outPath, Conformance conformance) throws Exception
{
// Open input document
try (FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr))
{
// Create the Validator object, and use the Conformance object to create
// an AnalysisOptions object that controls the behavior of the Validator.
Validator validator = new Validator();
AnalysisOptions analysisOptions = new AnalysisOptions();
analysisOptions.setConformance(conformance);

// Run the analysis, and check the results.
// Only proceed if document is not conforming.
AnalysisResult analysisResult = validator.analyze(inDoc, analysisOptions);
if (analysisResult.getIsConforming())
{
System.out.println("Document conforms to " + inDoc.getConformance() + " already.");
return;
}

// Create output stream
try (FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW))
{
// Create a converter object
Converter converter = new Converter();

// Add handler for conversion events
class EventListener implements ConversionEventListener
{
private EventSeverity eventsSeverity = EventSeverity.INFORMATION;

public EventSeverity getEventsSeverity() {
return eventsSeverity;
}

@Override
public void conversionEvent(ConversionEvent event) {
// Get the event's suggested severity
EventSeverity severity = event.getSeverity();

// Optionally the suggested severity can be changed according to
// the requirements of your conversion process and, for example,
// the event's category (e.Category).

if (severity.ordinal() > eventsSeverity.ordinal())
eventsSeverity = severity;

// Report conversion event
System.out.format("- %c %s: %s (%s%s)%n", severity.toString().charAt(0), event.getCategory(), event.getMessage(), event.getContext(), event.getPageNo() > 0 ? " on page " + event.getPageNo() : "");
}
}
EventListener el = new EventListener();

converter.addConversionEventListener(el);

// Convert the input document to PDF/A using the converter object
// and its conversion event handler
try (Document outDoc = converter.convert(analysisResult, inDoc, outStr))
{
// Check if critical conversion events occurred
switch (el.getEventsSeverity())
{
case INFORMATION:
System.out.println("Successfully converted document to " + outDoc.getConformance() + ".");
break;

case WARNING:
System.out.println("Warnings occurred during the conversion of document to " + outDoc.getConformance() + ".");
System.out.println("Check the output file to decide if the result is acceptable.");
break;

case ERROR:
throw new Exception("Unable to convert document to " + conformance + " because of critical conversion events.");
}
}
}

}
}
Download code sample
def convert_if_not_conforming(input_file_path: str, output_file_path: str, conformance: Conformance):
with io.FileIO(input_file_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:

# Create the Validator object, and use the Conformance object to create
# an AnalysisOptions object that controls the behavior of the Validator.
validator = Validator()
analysis_options = AnalysisOptions()
analysis_options.conformance = conformance

# Run the analysis, and check the results.
# Only proceed if document is not conforming.
analysis_result = validator.analyze(input_document, analysis_options)
if analysis_result.is_conforming:
print(f"Document conforms to {input_document.conformance.name} already.")
return

# Create a converter object
converter = Converter()

# Add handler for conversion events
converter.add_conversion_event_handler(event_handler)

with io.FileIO(output_file_path, 'wb+') as output_stream:

# Convert the input document to PDF/A using the converter object
# and its conversion event handler
output_document = converter.convert(analysis_result, input_document, output_stream, None)

# Check if critical conversion events occurred
match events_severity:
case EventSeverity.INFORMATION:
print(f"Successfully converted document to {output_document.conformance.name}.")

case EventSeverity.WARNING:
print(f"Warnings occurred during the conversion of document to {output_document.conformance.name}.")
print("Check the output file to decide if the result is acceptable.")

case EventSeverity.ERROR:
raise Exception(f"Unable to convert document to {conformance.name} because of critical conversion events.")
def event_handler(data_part: str, message: str, severity: EventSeverity, category: EventCategory, code: EventCode, context_info: str, page_no: int):
# Get the event's suggested severity
suggested_severity = severity

# Optionally, the suggested severity can be changed according to
# the requirements of your conversion process and, for example,
# the event's category.

global events_severity

if suggested_severity > events_severity:
events_severity = suggested_severity

# Report conversion event
if suggested_severity == EventSeverity.INFORMATION:
severity_char = 'I'
elif suggested_severity == EventSeverity.WARNING:
severity_char = 'W'
else:
severity_char = 'E'

if page_no > 0:
print(f"- {severity_char} {category.name}: {message} ({context_info} on page {page_no})")
else:
print(f"- {severity_char} {category.name}: {message} ({context_info})")
# Define global events_severity
events_severity = EventSeverity.INFORMATION
convert_if_not_conforming(input_file_path, output_file_path, conformance)
Download code sample
Sub ConvertIfNotConforming(inPath As String, outPath As String, conformance As Conformance)
' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)
' Create the Validator object, and use the Conformance object to create
' an AnalysisOptions object that controls the behavior of the Validator.
Dim validator = New Validator()
Dim analysisOptions = New AnalysisOptions() With {.conformance = conformance}

' Run the analysis, and check the results.
' Only proceed if document is not conforming.
Dim analysisResult = validator.Analyze(inDoc, analysisOptions)
If analysisResult.IsConforming Then
Console.WriteLine($"Document conforms to {inDoc.Conformance} already.")
Return
End If

' Create a converter object
Dim converter = New Converter()

' Add handler for conversion events
Dim eventsSeverity = EventSeverity.Information
AddHandler converter.ConversionEvent, Sub(s, e)
' Get the event's suggested severity
Dim severity = e.Severity

' Optionally the suggested severity can be changed according to
' the requirements of your conversion process and, for example,
' the event's category (e.Category).

If severity > eventsSeverity Then
eventsSeverity = severity
End If

' Report conversion event
Console.WriteLine("- {0} {1}: {2} ({3}{4})",
severity.ToString()(0), e.Category, e.Message, e.Context, If(e.PageNo > 0, " page " & e.PageNo, "")
)
End Sub

' Create stream for output file
Using outStr = File.Create(outPath)
' Convert the input document to PDF/A using the converter object
' and its conversion event handler
Using outDoc = converter.Convert(analysisResult, inDoc, outStr)
' Check if critical conversion events occurred
Select Case eventsSeverity
Case EventSeverity.Information
Console.WriteLine($"Successfully converted document to {outDoc.Conformance}.")
Case EventSeverity.Warning
Console.WriteLine($"Warnings occurred during the conversion of document to {outDoc.Conformance}.")
Console.WriteLine($"Check the output file to decide if the result is acceptable.")
Case EventSeverity.Error
Throw New Exception($"Unable to convert document to {conformance} because of critical conversion events.")
End Select
End Using
End Using
End Using
End Using
End Sub

Create a ZUGFeRD invoice

Download code sample
void EventListener(void* pContext, const char* szDataPart, const char* szMessage,
TPdfToolsPdfAConversion_EventSeverity iSeverity, TPdfToolsPdfAConversion_EventCategory iCategory,
TPdfToolsPdfAConversion_EventCode iCode, const char* szContext, int iPageNo)
{
// iSeverity is the event's suggested severity
// Optionally the suggested severity can be changed according to
// the requirements of your conversion process and, for example,
// the event's category (e.Category).

if (iSeverity > iEventsSeverity)
iEventsSeverity = iSeverity;

// Report conversion event
TCHAR cSeverity = iSeverity == ePdfToolsPdfAConversion_EventSeverity_Information ? 'I'
: ePdfToolsPdfAConversion_EventSeverity_Warning ? 'W'
: 'E';
if (iPageNo > 0)
_tprintf(_T("- %c %d: %s (%s on page %d)\n"), cSeverity, iCategory, szMessage, szContext, iPageNo);
else
_tprintf(_T("- %c %d: %s (%s)\n"), cSeverity, iCategory, szMessage, szContext);
}
void AddZugferdInvoice(const TCHAR* szInPath, const TCHAR* szInvoicePath, const TCHAR* szOutPath)
{
TPdfToolsPdfAValidation_AnalysisOptions* pAOpt = NULL;
TPdfToolsPdfAValidation_Validator* pValidator = NULL;
TPdfToolsPdfAValidation_AnalysisResult* pARes = NULL;
TPdfToolsPdfAConversion_ConversionOptions* pConvOpt = NULL;
TPdfToolsPdfAConversion_Converter* pConv = NULL;
TPdfToolsPdf_Document* pOutDoc = NULL;
TPdfToolsPdf_Document* pInDoc = NULL;
FILE* pInStream = NULL;
FILE* pInvoiceStream = NULL;
FILE* pOutStream = NULL;

// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Failed to open document \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrBuf, PdfTools_GetLastError());

// Create validator to analyze PDF/A standard conformance of input document
pAOpt = PdfToolsPdfAValidation_AnalysisOptions_New();
// The conformance has to be set to PDF/A-3 when adding the XML invoice file
PdfToolsPdfAValidation_AnalysisOptions_SetConformance(pAOpt, ePdfToolsPdf_Conformance_PdfA3U);
pValidator = PdfToolsPdfAValidation_Validator_New();
pARes = PdfToolsPdfAValidation_Validator_Analyze(pValidator, pInDoc, pAOpt);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pARes, _T("Failed to analyze document. %s (ErrorCode: 0x%08x).\n"), szErrBuf,
PdfTools_GetLastError());

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to create the output file \"%s\".\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Create a converter object and add a conversion event handler
pConvOpt = PdfToolsPdfAConversion_ConversionOptions_New();
pConv = PdfToolsPdfAConversion_Converter_New();
PdfToolsPdfAConversion_Converter_AddConversionEventHandlerA(
pConv, NULL, (TPdfToolsPdfAConversion_Converter_ConversionEventA)EventListener);

// Create invoice stream for reading
pInvoiceStream = _tfopen(szInvoicePath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInvoiceStream, _T("Failed to open the invoice file \"%s\" for reading.\n"),
szInvoicePath);
TPdfToolsSys_StreamDescriptor invoiceDesc;
PdfToolsSysCreateFILEStreamDescriptor(&invoiceDesc, pInvoiceStream, 0);
// Add invoice XML file
PdfToolsPdfAConversion_Converter_AddInvoiceXml(pConv, ePdfToolsPdfAConversion_InvoiceType_Zugferd, &invoiceDesc,
NULL);
// Convert the input document to PDF/A-3U
pOutDoc = PdfToolsPdfAConversion_Converter_Convert(pConv, pARes, pInDoc, &outDesc, pConvOpt, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Failed to convert document. %s (ErrorCode: 0x%08x).\n"), szErrBuf,
PdfTools_GetLastError());

// Check if critical conversion events occurred
switch (iEventsSeverity)
{
case ePdfToolsPdfAConversion_EventSeverity_Information:
{
TPdfToolsPdf_Conformance iOutConf;
PdfToolsPdf_Document_GetConformance(pOutDoc, &iOutConf);
printf("Successfully converted document to %s.\n", PdfToolsPdf_Conformance_ToStringA(iOutConf));
break;
}

case ePdfToolsPdfAConversion_EventSeverity_Warning:
{
TPdfToolsPdf_Conformance iOutConf;
PdfToolsPdf_Document_GetConformance(pOutDoc, &iOutConf);
printf("Warnings occurred during the conversion of document to %s.\n",
PdfToolsPdf_Conformance_ToStringA(iOutConf));
printf("Check the output file to decide if the result is acceptable.\n");
break;
}

case ePdfToolsPdfAConversion_EventSeverity_Error:
{
printf("Unable to convert document to PDF/A-3U because of critical conversion events.\n");
break;
}
}

cleanup:
PdfToolsPdf_Document_Close(pOutDoc);
PdfTools_Release(pConv);
PdfTools_Release(pConvOpt);
PdfTools_Release(pARes);
PdfTools_Release(pValidator);
PdfTools_Release(pAOpt);
PdfToolsPdf_Document_Close(pInDoc);
if (pInStream)
fclose(pInStream);
if (pOutStream)
fclose(pOutStream);
if (pInvoiceStream)
fclose(pInvoiceStream);
}
Download code sample
static void AddZugferdInvoice(string inPath, string invoicePath, string outPath)
{
// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create the Validator object, and use the Conformance object to create
// an AnalysisOptions object that controls the behavior of the Validator.
var validator = new Validator();
// The conformance has to be set to PDF/A-3 when adding the XML invoice file
var analysisOptions = new AnalysisOptions() { Conformance = new Conformance(3, Conformance.PdfALevel.U) };

// Run the analysis
var analysisResult = validator.Analyze(inDoc, analysisOptions);

// Create a converter object
var converter = new Converter();

// Add invoice XML file
using var invoiceStr = File.OpenRead(invoicePath);
converter.AddInvoiceXml(InvoiceType.Zugferd, invoiceStr);

// Add handler for conversion events
var eventsSeverity = EventSeverity.Information;
converter.ConversionEvent += (s, e) =>
{
// Get the event's suggested severity
var severity = e.Severity;

// Optionally the suggested severity can be changed according to
// the requirements of your conversion process and, for example,
// the event's category (e.Category).

if (severity > eventsSeverity)
eventsSeverity = severity;

// Report conversion event
Console.WriteLine("- {0} {1}: {2} ({3}{4})",
severity.ToString()[0], e.Category, e.Message, e.Context, e.PageNo > 0 ? " page " + e.PageNo : ""
);
};

// Create stream for output file
using var outStr = File.Create(outPath);

// Convert the input document to PDF/A using the converter object
// and its conversion event handler
using var outDoc = converter.Convert(analysisResult, inDoc, outStr);

// Check if critical conversion events occurred
switch (eventsSeverity)
{
case EventSeverity.Information:
Console.WriteLine($"Successfully converted document to {outDoc.Conformance}.");
break;

case EventSeverity.Warning:
Console.WriteLine($"Warnings occurred during the conversion of document to {outDoc.Conformance}.");
Console.WriteLine($"Check the output file to decide if the result is acceptable.");
break;

case EventSeverity.Error:
throw new Exception($"Unable to convert document to PDF/A-3U because of critical conversion events.");
}
}
Download code sample
    private static void addZugferdInvoice(String inPath, String invoicePath, String outPath) throws Exception
{
// Open input document
try (FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr))
{
// Create the Validator object, and use the Conformance object to create
// an AnalysisOptions object that controls the behavior of the Validator.
Validator validator = new Validator();
AnalysisOptions analysisOptions = new AnalysisOptions();
// The conformance has to be set to PDF/A-3 when adding the XML invoice file
analysisOptions.setConformance(new Conformance(new Conformance.PdfAVersion(3, Conformance.PdfAVersion.Level.U)));

// Run the analysis
AnalysisResult analysisResult = validator.analyze(inDoc, analysisOptions);

// Create output stream
try (FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW))
{
// Create a converter object
Converter converter = new Converter();

// Add invoice XML file
try (FileStream invoiceStr = new FileStream(invoicePath, FileStream.Mode.READ_ONLY))
{
converter.addInvoiceXml(InvoiceType.ZUGFERD, invoiceStr);

// Add handler for conversion events
class EventListener implements ConversionEventListener
{
private EventSeverity eventsSeverity = EventSeverity.INFORMATION;

public EventSeverity getEventsSeverity() {
return eventsSeverity;
}

@Override
public void conversionEvent(ConversionEvent event) {
// Get the event's suggested severity
EventSeverity severity = event.getSeverity();

// Optionally the suggested severity can be changed according to
// the requirements of your conversion process and, for example,
// the event's category (e.Category).

if (severity.ordinal() > eventsSeverity.ordinal())
eventsSeverity = severity;

// Report conversion event
System.out.format("- %c %s: %s (%s%s)%n", severity.toString().charAt(0), event.getCategory(), event.getMessage(), event.getContext(), event.getPageNo() > 0 ? " on page " + event.getPageNo() : "");
}
}
EventListener el = new EventListener();

converter.addConversionEventListener(el);

// Convert the input document to PDF/A using the converter object
// and its conversion event handler
try (Document outDoc = converter.convert(analysisResult, inDoc, outStr))
{
// Check if critical conversion events occurred
switch (el.getEventsSeverity())
{
case INFORMATION:
System.out.println("Successfully converted document to " + outDoc.getConformance() + ".");
break;

case WARNING:
System.out.println("Warnings occurred during the conversion of document to " + outDoc.getConformance() + ".");
System.out.println("Check the output file to decide if the result is acceptable.");
break;

case ERROR:
throw new Exception("Unable to convert document to PDF/A-3U because of critical conversion events.");
}
}
}
}
}
}
Download code sample
def add_zugferd_invoice(input_path: str, zugferd_xml_path: str, output_path: str):
# Open input document
with io.FileIO(input_path, 'rb') as input_stream:
with Document.open(input_stream) as input_document:
# Create the Validator object, and use the Conformance object to create
# an AnalysisOptions object that controls the behavior of the Validator.
validator = Validator()
# The conformance has to be set to PDF/A-3 when adding the XML invoice file
analysis_options = AnalysisOptions()
analysis_options.conformance = Conformance.PDF_A3_U

# Run the analysis
analysis_result = validator.analyze(input_document, analysis_options)

# Create a converter object
converter = Converter()

# Add the invoice XML file
with io.FileIO(zugferd_xml_path, 'rb') as invoice_stream:
converter.add_invoice_xml(InvoiceType.ZUGFERD, invoice_stream)

# Add handler for conversion events
event_severity_holder = [EventSeverity.INFORMATION]
converter.add_conversion_event_handler(lambda *args: handle_conversion_event(*args, event_severity_holder))

# Create output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Convert the input document to PDF/A
with converter.convert(analysis_result, input_document, output_stream) as output_document:
if event_severity_holder[0] == EventSeverity.INFORMATION:
print(f"Successfully converted document to {output_document.conformance.name}.")
elif event_severity_holder[0] == EventSeverity.WARNING:
print(f"Warnings occurred during the conversion to {output_document.conformance}.")
print("Check the output file to decide if the result is acceptable.")
elif event_severity_holder[0] == EventSeverity.ERROR:
raise Exception(f"Unable to convert document to PDF/A-3U because of critical conversion events.")
def handle_conversion_event(data_part: str, message: str, severity: EventSeverity, category: EventCategory, code: EventCode, context: str, page_no: int, event_severity_holder: list[EventSeverity]):
# Optionally the suggested severity can be changed according to
# the requirements of your conversion process and, for example,
# the event's category (e.Category).

if severity > event_severity_holder[0]:
event_severity_holder[0] = severity

print(f"- {severity.name} {category.name}: {message} ({context}{f' on page {page_no}' if page_no > 0 else ''})")
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

add_zugferd_invoice(input_path, zugferd_xml_path, output_path)
Download code sample
Sub AddZugferdInvoice(inPath As String, invoicePath As String, outPath As String)
' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create the Validator object, and use the Conformance object to create
' an AnalysisOptions object that controls the behavior of the Validator.
Dim validator = New Validator()
' The conformance has to be set to PDF/A-3 when adding the XML invoice file
Dim analysisOptions = New AnalysisOptions() With {.Conformance = New Conformance(3, Conformance.PdfALevel.U)}

' Run the analysis
Dim analysisResult = validator.Analyze(inDoc, analysisOptions)

' Create a converter object
Dim converter = New Converter()

' Add invoice XML file
Using invoiceStr = File.OpenRead(invoicePath)
converter.AddInvoiceXml(InvoiceType.Zugferd, invoiceStr)

' Add handler for conversion events
Dim eventsSeverity = EventSeverity.Information
AddHandler converter.ConversionEvent, Sub(s, e)
' Get the event's suggested severity
Dim severity = e.Severity

' Optionally the suggested severity can be changed according to
' the requirements of your conversion process and, for example,
' the event's category (e.Category).

If severity > eventsSeverity Then
eventsSeverity = severity
End If

' Report conversion event
Console.WriteLine("- {0} {1}: {2} ({3}{4})", severity.ToString()(0), e.Category, e.Message, e.Context, If(e.PageNo > 0, " page " & e.PageNo, ""))
End Sub

' Create stream for output file
Using outStr = File.Create(outPath)

' Convert the input document to PDF/A using the converter object
' and its conversion event handler
Using outDoc = converter.Convert(analysisResult, inDoc, outStr)

' Check if critical conversion events occurred
Select Case eventsSeverity
Case EventSeverity.Information
Console.WriteLine($"Successfully converted document to {outDoc.Conformance}.")
Case EventSeverity.Warning
Console.WriteLine($"Warnings occurred during the conversion of document to {outDoc.Conformance}.")
Console.WriteLine($"Check the output file to decide if the result is acceptable.")
Case EventSeverity.Error
Throw New Exception($"Unable to convert document to PDF/A-3U because of critical conversion events.")
End Select
End Using
End Using
End Using
End Using
End Using
End Sub

Converting documents to rasterized images

Convert PDF to image

Download code sample
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Create the profile that defines the conversion parameters.
// The Archive profile converts PDF documents to TIFF images for archiving.
pProfile = (TPdfToolsPdf2ImageProfiles_Profile*)PdfToolsPdf2ImageProfiles_Archive_New();

// Optionally the profile's parameters can be changed according to the
// requirements of your conversion process.

// Convert the PDF document to an image document
pConverter = PdfToolsPdf2Image_Converter_New();
pOutDoc =
(TPdfToolsImage_Document*)PdfToolsPdf2Image_Converter_ConvertDocument(pConverter, pInDoc, &outDesc, pProfile);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());
Download code sample
private static void Pdf2Image(string inPath, string outPath)
{
// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create the profile that defines the conversion parameters.
// The Archive profile converts PDF documents to TIFF images for archiving.
var profile = new Profiles.Archive();

// Optionally the profile's parameters can be changed according to the
// requirements of your conversion process.

// Create output stream
using var outStr = File.Create(outPath);

// Convert the PDF document to an image document
using var outDoc = new Converter().ConvertDocument(inDoc, outStr, profile);
}
Download code sample
private static void pdf2Image(String inPath, String outPath) throws Exception
{
// Create the profile that defines the conversion parameters.
// The Archive profile converts PDF documents to TIFF images for archiving.
Archive profile = new Archive();

// Optionally the profile's parameters can be changed according to the
// requirements of your conversion process.

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Convert the PDF document to an image document
com.pdftools.image.Document outDoc = new Converter().convertDocument(inDoc, outStream, profile))
{
}
}
Download code sample
def pdf_to_image(input_pdf_path: str, output_image_path: str):
# Open input document
with io.FileIO(input_pdf_path, 'rb') as input_pdf_stream:
with Document.open(input_pdf_stream) as input_pdf_document:
# Create the profile that defines the conversion parameters.
# The Archive profile converts PDF documents to TIFF images for archiving.
profile = Archive()

# Optionally the profile's parameters can be changed according to the
# requirements of your conversion process.

# Create output stream
with io.FileIO(output_image_path, 'wb+') as output_stream:
# Convert the PDF document to an image document
converter = Converter()
converter.convert_document(input_pdf_document, output_stream, profile)
pdf_to_image(input_pdf_path, output_image_path)
Download code sample
Private Sub Pdf2Image(inPath As String, outPath As String)
' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create the profile that defines the conversion parameters.
' The Archive profile converts PDF documents to TIFF images for archiving.
Dim profile = New Profiles.Archive()

' Optionally the profile's parameters can be changed according to the
' requirements of your conversion process.

' Create output stream
Using outStr = File.Create(outPath)

' Convert the PDF document to an image document
Using outDoc = New Converter().ConvertDocument(inDoc, outStr, profile)
End Using
End Using
End Using
End Using
End Sub

Converting images to PDF documents

Convert an image to an accessible PDF/A document

Download code sample
private static void Image2Pdf(string inPath, string alternateText, string outPath)
{
// Open image document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create the profile that defines the conversion parameters.
// The Archive profile converts images to PDF/A documents for archiving.
var profile = new Profiles.Archive();

// Set conformance of output document to PDF/A-2a
profile.Conformance = new Conformance(2, Conformance.PdfALevel.A);

// For PDF/A level A, an alternate text is required for each page of the image.
// This is optional for other PDF/A levels, e.g. PDF/A-2b.
profile.Language = "en";
profile.AlternateText.Add(alternateText);

// Optionally other profile parameters can be changed according to the
// requirements of your conversion process.

// Create output stream
using var outStr = File.Create(outPath);

// Convert the image to a tagged PDF/A document
using var outDoc = new Converter().Convert(inDoc, outStr, profile);
}
Download code sample
private static void image2Pdf(String inPath, String alternateText, String outPath) throws Exception
{
// Create the profile that defines the conversion parameters.
// The Archive profile converts images to PDF/A documents for archiving.
Archive profile = new Archive();

// Set conformance of output document to PDF/A-2a
profile.setConformance(new Conformance(new Conformance.PdfAVersion(2, Level.A)));

// For PDF/A level A, an alternate text is required for each page of the image.
// This is optional for other PDF/A levels, e.g. PDF/A-2b.
profile.setLanguage("en");
profile.getAlternateText().add(alternateText);

// Optionally other profile parameters can be changed according to the
// requirements of your conversion process.

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Convert the image to a tagged PDF/A document
com.pdftools.pdf.Document outDoc = new Converter().convert(inDoc, outStream, profile))
{
}
}
Download code sample
def image_to_pdf(input_path: str, alternate_text: str, output_path: str):
# Open image document
with io.FileIO(input_path, 'rb') as image_stream:
with Document.open(image_stream) as image_document:
# Create the profile that defines the conversion parameters.
# The Archive profile converts images to PDF/A documents for archiving.
profile = Archive()

# Set conformance of output document to PDF/A-2a
profile.conformance = Conformance.PDF_A2_A

# For PDF/A level A, an alternate text is required for each page of the image.
# This is optional for other PDF/A levels, e.g. PDF/A-2b.
profile.language = "en"
profile.alternate_text.append(alternate_text)

# Optionally other profile parameters can be changed according to the
# requirements of your conversion process.

# Create output stream
with io.FileIO(output_path, 'wb+') as output_stream:
# Convert the image to a tagged PDF/A document
converter = Converter()
converter.convert(image_document, output_stream, profile)
image_to_pdf(input_path, alternate_text, output_path)
Download code sample
Private Sub Image2Pdf(inPath As String, alternateText As String, outPath As String)
' Open image document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create the profile that defines the conversion parameters.
' The Archive profile converts images to PDF/A documents for archiving.
Dim profile = New Profiles.Archive()

' Set conformance of output document to PDF/A-2a
profile.Conformance = New Conformance(2, Conformance.PdfALevel.A)

' For PDF/A level A, an alternate text is required for each page of the image.
' This is optional for other PDF/A levels, e.g. PDF/A-2b.
profile.Language = "en"
profile.AlternateText.Add(alternateText)

' Optionally other profile parameters can be changed according to the
' requirements of your conversion process.

' Create output stream
Using outStr = File.Create(outPath)

' Convert the image to a tagged PDF/A document
Using outDoc = New Converter().Convert(inDoc, outStr, profile)
End Using
End Using
End Using
End Using
End Sub

Convert image to PDF

Download code sample
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsImage_Document_Open(&inDesc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Create the profile that defines the conversion parameters.
// The Default profile converts images to PDF documents.
pProfile = (TPdfToolsImage2PdfProfiles_Profile*)PdfToolsImage2PdfProfiles_Default_New();

// Convert the image to a PDF document
pConverter = PdfToolsImage2Pdf_Converter_New();
pOutDoc = (TPdfToolsPdf_Document*)PdfToolsImage2Pdf_Converter_Convert(pConverter, pInDoc, &outDesc, pProfile, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());
Download code sample
private static void Image2Pdf(string inPath, string outPath)
{
// Open image document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create the profile that defines the conversion parameters.
// The Default profile converts images to PDF documents.
var profile = new Profiles.Default();

// Optionally, the profile's parameters can be changed according to the
// requirements of your conversion process.

// Create output stream
using var outStr = File.Create(outPath);

// Convert the image to a PDF document
using var outDoc = new Converter().Convert(inDoc, outStr, profile);
}
Download code sample
private static void image2Pdf(String inPath, String outPath) throws Exception
{
// Create the profile that defines the conversion parameters.
// The Default profile converts images to PDF documents.
Default profile = new Default();

// Optionally, the profile's parameters can be changed according to the
// requirements of your conversion process.

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Convert the image to a PDF document
com.pdftools.pdf.Document outDoc = new Converter().convert(inDoc, outStream, profile))
{
}
}
Download code sample
def convert_image_to_pdf(input_path: str, output_path: str):
# Open image document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:

# Create the profile that defines the conversion parameters (Default profile)
profile = Default()

# Optionally, you can adjust the profile's parameters if needed

# Create output stream
with io.FileIO(output_path, 'wb+') as output_stream:

# Convert the image to a PDF document
converter = Converter()
converter.convert(input_document, output_stream, profile)
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

convert_image_to_pdf(input_path, output_path)
Download code sample
Private Sub Image2Pdf(inPath As String, outPath As String)
' Open image document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create the profile that defines the conversion parameters.
' The Default profile converts images to PDF documents.
Dim profile = New Profiles.Default()

' Optionally, the profile's parameters can be changed according to the
' requirements of your conversion process.

' Create output stream
Using outStr = File.Create(outPath)

' Convert the image to a PDF document
Using outDoc = New Converter().Convert(inDoc, outStr, profile)
End Using
End Using
End Using
End Using
End Sub

Convert multiple images to a PDF

Download code sample
private static void Images2Pdf(IEnumerable<string> inPaths, string outPath)
{
var streams = new List<FileStream>();
var images = new DocumentList();
try
{
// Open input images and store in list
foreach (var inPath in inPaths)
{
var stream = File.OpenRead(inPath);
streams.Add(stream);
images.Add(Document.Open(stream));
}

// Create the profile that defines the conversion parameters.
var profile = new Profiles.Default();

// Optionally the profile's parameters can be changed according to the
// requirements of your conversion process.

// Create output stream
using var outStream = File.Create(outPath);
using var outPdf = new Converter().ConvertMultiple(images, outStream, profile);
}
finally
{
foreach (var image in images)
image.Dispose();
foreach (var stream in streams)
stream.Dispose();
}
}
Download code sample
private static void Images2Pdf(String[] inPaths, String outPath) throws Exception
{
// Create the profile that defines the conversion parameters.
Default profile = new Default();

List<FileStream> streams = new ArrayList<>();
DocumentList images = new DocumentList();

// Optionally the profile's parameters can be changed according to the
// requirements of your conversion process.
try {
// Open input documents
for (String inPath : inPaths) {
FileStream stream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
streams.add(stream);
images.add(Document.open(stream));
}

try (
// Create output stream
FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
// Convert the image to a PDF document
com.pdftools.pdf.Document outDoc = new Converter().convertMultiple(images, outStream, profile)) {
}
}
finally {
for (Document image : images)
image.close();
for (FileStream stream : streams)
stream.close();
}
}
Download code sample
def images_to_pdf(input_image_paths: list[str], output_file_path: str):
try:
stream_list = []
images = ImageDocumentList()

# Open input images and store in list
for input_image_path in input_image_paths:
image_stream = io.FileIO(input_image_path, 'rb')
stream_list.append(image_stream)
images.append(ImageDocument.open(image_stream))

# Create the profile that defines the conversion parameters.
profile = Default()

# Optionally the profile's parameters can be changed according to the
# requirements of your conversion process.

# Create output stream
with io.FileIO(output_file_path, 'wb+') as output_stream:
converter = Converter()
converter.convert_multiple(images, output_stream, profile)
finally:
if 'images' in locals():
for image in images:
image.__exit__(None, None, None)
if 'stream_list' in locals():
for stream in stream_list:
stream.__exit__(None, None, None)
images_to_pdf(input_image_paths, output_file_path)
Download code sample
Private Sub Images2Pdf(inPaths As IEnumerable(Of String), outPath As String)
Dim streams = New List(Of FileStream)()
Dim images = New DocumentList()
Try
' Open input images and store in list
For Each inPath In inPaths
Dim stream = File.OpenRead(inPath)
streams.Add(stream)
images.Add(Document.Open(stream))
Next

' Create the profile that defines the conversion parameters.
Dim profile = New Profiles.Default()

' Optionally the profile's parameters can be changed according to the
' requirements of your conversion process.
' Create output stream
Using outStream = File.Create(outPath)
Using outPdf = New Converter().ConvertMultiple(images, outStream, profile)
End Using
End Using
Finally
For Each item In images
item.Dispose()
Next
For Each stream In streams
stream.Dispose()
Next
End Try
End Sub

Encrypt documents

Decrypt an encrypted PDF

Download code sample
// Use password to open encrypted input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, szPassword);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Check if input file is encrypted
BOOL bIsGetPermissionsSuccessful = PdfToolsPdf_Document_GetPermissions(pInDoc, &iPermissions);
if (!bIsGetPermissionsSuccessful)
{
if (PdfTools_GetLastError() == 0)
{
_tprintf(_T("Validation failed, input file \"%s\" is not encrypted.\n"), szInPath);
iRet = 1;
goto cleanup;
}
else
{
nBufSize = PdfTools_GetLastErrorMessage(NULL, 0);
PdfTools_GetLastErrorMessage(szErrorBuff, MIN(ARRAY_SIZE(szErrorBuff), nBufSize));
_tprintf(_T("Failed to get permissions for input file \"%s\", error %s \n"), szInPath, szErrorBuff);
iRet = 1;
goto cleanup;
}
}

// Set encryption options
pOptions = PdfToolsSign_OutputOptions_New();

// Set encryption parameters to no encryption
PdfToolsPdf_OutputOptions_SetEncryption((TPdfToolsPdf_OutputOptions*)pOptions, NULL);

// Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
// (see warning category Sign.WarningCategory.SignedDocEncryptionUnchanged).
PdfToolsSign_OutputOptions_SetRemoveSignatures(pOptions, ePdfToolsSign_SignatureRemoval_Signed);

// Decrypt the document
pSigner = PdfToolsSign_Signer_New();
pOutDoc = PdfToolsSign_Signer_Process(pSigner, pInDoc, &outDesc, pOptions, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());

Download code sample
static void Decrypt(string password, string inPath, string outPath)
{
// Use password to open encrypted input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr, password);

if (inDoc.Permissions == null)
throw new Exception("Input file is not encrypted.");

// Create stream for output file
using var outStr = File.Create(outPath);

// Set encryption options
var outputOptions = new Sign.OutputOptions()
{
// Set encryption parameters to no encryption
Encryption = null,
// Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
// (see warning category Sign.WarningCategory.SignedDocEncryptionUnchanged).
RemoveSignatures = Sign.SignatureRemoval.Signed,
};

// Decrypt the document
using var outDoc = new Sign.Signer().Process(inDoc, outStr, outputOptions);
}
Download code sample
private static void decrypt(String password, String inPath, String outPath) throws Exception
{
try (
// Use password to open encrypted input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr, password))
{
if (inDoc.getPermissions() == null)
throw new Exception("Input file is not encrypted.");

// Set encryption options
OutputOptions outputOptions = new OutputOptions();

// Set encryption parameters to no encryption
outputOptions.setEncryption(null);

// Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
// (see warning category WarningCategory.SIGNED_DOC_ENCRYPTION_UNCHANGED).
outputOptions.setRemoveSignatures(SignatureRemoval.SIGNED);

try(
// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Decrypt the document
Document outDoc = new Signer().process(inDoc, outStr, outputOptions))
{
}
}
}
Download code sample
def decrypt(password, input_path, output_path):
# Use password to open encrypted input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream, password) as input_document:
if input_document.permissions == None:
print(f"Input file is not encrypted.")
return

# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Set encryption options
output_options = SignOutputOptions()
# Set encryption parameters to no encryption
output_options.encryption = None
# Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
# (see warning category Sign.WarningCategory.SignedDocEncryptionUnchanged).
output_options.remove_signatures = SignatureRemoval.SIGNED

# Decrypt the document
signer = Signer()
signer.process(input_document, output_stream, output_options)
# Decrypt a PDF document
decrypt(password, input_path, output_path)
Download code sample
Sub Decrypt(password As String, inPath As String, outPath As String)
' Use password to open encrypted input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr, password)

If inDoc.Permissions Is Nothing Then
Throw New Exception("Input file is not encrypted.")
End If

' Create stream for output file
Using outStr = File.Create(outPath)

' Set encryption options
Dim outputOptions = New Sign.OutputOptions() With {
.Encryption = Nothing,
.RemoveSignatures = Sign.SignatureRemoval.Signed
}

' Decrypt the document
Using outDoc = New Sign.Signer().Process(inDoc, outStr, outputOptions)
End Using
End Using
End Using
End Using
End Sub

Encrypt a PDF

Download code sample
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Set encryption options
pOptions = PdfToolsSign_OutputOptions_New();

// Set a user password that will be required to open the document.
// Note that this will remove PDF/A conformance of input files (see warning category
// ePdfToolsSign_WarningCategory_PdfARemoved)
pEncryption = PdfToolsPdf_Encryption_New(szPassword, NULL, ePdfToolsPdf_Permission_All);
PdfToolsPdf_OutputOptions_SetEncryption((TPdfToolsPdf_OutputOptions*)pOptions, pEncryption);

// Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
// (see warning category ePdfToolsSign_WarningCategory_SignedDocEncryptionUnchanged).
PdfToolsSign_OutputOptions_SetRemoveSignatures(pOptions, ePdfToolsSign_SignatureRemoval_Signed);

// Encrypt the document
pSigner = PdfToolsSign_Signer_New();
pOutDoc = PdfToolsSign_Signer_Process(pSigner, pInDoc, &outDesc, pOptions, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());

Download code sample
static void Encrypt(string password, string inPath, string outPath)
{
// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Set encryption options
var outputOptions = new Sign.OutputOptions()
{
// Set a user password that will be required to open the document.
// Note that this will remove PDF/A conformance of input files (see warning category Sign.WarningCategory.PdfARemoved)
Encryption = new Encryption(password, null, Permission.All),
// Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
// (see warning category Sign.WarningCategory.SignedDocEncryptionUnchanged).
RemoveSignatures = Sign.SignatureRemoval.Signed,
};

// Encrypt the document
using var outDoc = new Sign.Signer().Process(inDoc, outStr, outputOptions);
}
Download code sample
private static void encrypt(String password, String inPath, String outPath) throws Exception
{
try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr))
{
// Set encryption options
OutputOptions outputOptions = new OutputOptions();

// Set a user password that will be required to open the document.
// Note that this will remove PDF/A conformance of input files (see warning category WarningCategory.PDF_A_REMOVED)
outputOptions.setEncryption(new Encryption(password, null, Permission.ALL));

// Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
// (see warning category WarningCategory.SIGNED_DOC_ENCRYPTION_UNCHANGED).
outputOptions.setRemoveSignatures(SignatureRemoval.SIGNED);

try(
// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Encrypt the document
Document outDoc = new Signer().process(inDoc, outStr, outputOptions))
{
}
}
}
Download code sample
def encrypt(password: str, input_path: str, output_path: str):
# Open input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:
# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Set encryption options
output_options = SignOutputOptions()
# Set a user password that will be required to open the document.
# Note that this will remove PDF/A conformance of input files (see warning category Sign.WarningCategory.PdfARemoved)
output_options.encryption = Encryption(password, None, Permission.ALL)
# Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
# (see warning category Sign.WarningCategory.SignedDocEncryptionUnchanged).
output_options.remove_signatures = SignatureRemoval.SIGNED

# Encrypt the document
signer = Signer()
signer.process(input_document, output_stream, output_options)
# Encrypt a PDF document
encrypt(password, input_path, output_path)
Download code sample
Sub Encrypt(password As String, inPath As String, outPath As String)
' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Set encryption options
Dim outputOptions = New Sign.OutputOptions() With {
.Encryption = New Encryption(password, Nothing, Permission.All),
.RemoveSignatures = Sign.SignatureRemoval.Signed
}

' Encrypt the document
Using outDoc = New Sign.Signer().Process(inDoc, outStr, outputOptions)
End Using
End Using
End Using
End Using
End Sub

Getting started

Hello, Pdftools SDK!

Download code sample
// 1. Open input image document using memory stream
pCoverImageStream = _tfopen(szCoverImagePath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCoverImageStream, _T("Failed to open the input file \"%s\" for reading.\n"),
szCoverImagePath);
PdfToolsSysCreateFILEStreamDescriptor(&inImageDesc, pCoverImageStream, 0);
pCoverImageDoc = PdfToolsImage_Document_Open(&inImageDesc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pCoverImageDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"),
szCoverImagePath, szErrorBuff, PdfTools_GetLastError());

// 2. Create output stream in memory for the cover page (image as PDF)
PdfToolsSys_MemoryStreamDescriptor_Create(&outImageDesc);
pProfile = (TPdfToolsImage2PdfProfiles_Profile*)PdfToolsImage2PdfProfiles_Default_New();
pConverter = PdfToolsImage2Pdf_Converter_New();
pOutCoverPdfDoc = (TPdfToolsPdf_Document*)PdfToolsImage2Pdf_Converter_Convert(pConverter, pCoverImageDoc,
&outImageDesc, pProfile, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pOutCoverPdfDoc, "The processing 'Image to PDF' has failed. (ErrorCode: 0x%08x).\n", PdfTools_GetLastError());

// 3. Open input content document in-memory
pInputPdfStream = _tfopen(szInContentPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInputPdfStream, _T("Failed to open the input file \"%s\" for reading.\n"),
szInContentPath);
PdfToolsSysCreateFILEStreamDescriptor(&inContentDesc, pInputPdfStream, 0);
pInContentDoc = PdfToolsPdf_Document_Open(&inContentDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInContentDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"),
szInContentPath, szErrorBuff, PdfTools_GetLastError());

// 4. Create final output document in-memory
pOutFinalStream = _tfopen(szOutFinalPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFinalStream, _T("Failed to create output file \"%s\" for writing.\n"),
szOutFinalPath);
PdfToolsSysCreateFILEStreamDescriptor(&outFinalDesc, pOutFinalStream, 0);
pAssembler = PdfToolsDocumentAssembly_DocumentAssembler_New(&outFinalDesc, NULL, NULL);

// Define first and last page (only one page for the cover)
int firstPage = 1;
int lastPage = 1;
// 5. Append the first page of the image document to the final output
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PdfToolsDocumentAssembly_DocumentAssembler_Append(
pAssembler, pOutCoverPdfDoc, &firstPage, &lastPage, NULL, NULL),
"Failed to append the image document. (ErrorCode: 0x%08x).\n",
PdfTools_GetLastError());

// 6. Append content document to the final output
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
PdfToolsDocumentAssembly_DocumentAssembler_Append(pAssembler, pInContentDoc, NULL, NULL, NULL, NULL),
"Failed to append the content document. (ErrorCode: 0x%08x).\n", PdfTools_GetLastError());

// 7. Merge input documents into an output document
pOutFinalDoc = PdfToolsDocumentAssembly_DocumentAssembler_Assemble(pAssembler);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pOutFinalDoc,
"The processing of merging the first page with the PDF content has failed. (ErrorCode: 0x%08x).\n",
PdfTools_GetLastError());
Download code sample
private static void Image2Pdf(string inPath, MemoryStream imageStream)
{
// Open image document
using var inStr = File.OpenRead(inPath);
using var inDoc = PdfTools.Image.Document.Open(inStr);

// Create the profile that defines the conversion parameters.
// The Default profile converts images to PDF documents.
var profile = new Profiles.Default();

// Optionally, the profile's parameters can be changed according to the
// requirements of your conversion process.

// Convert the image to a PDF document
var outDoc = new Converter().Convert(inDoc, imageStream, profile);
}
private static void Merge(MemoryStream coverStream, FileStream inputContentStream, string outPath)
{
// Create output stream
using var outStream = File.Create(outPath);
using var docAssembler = new PdfTools.DocumentAssembly.DocumentAssembler(outStream);

docAssembler.Append(PdfTools.Pdf.Document.Open(coverStream), 1, 1);
docAssembler.Append(PdfTools.Pdf.Document.Open(inputContentStream));

// Merge input documents into an output document
docAssembler.Assemble();
}
Download code sample
private static void image2Pdf(String inPath, MemoryStream imageStream) throws Exception {
// Create the profile that defines the conversion parameters.
Default profile = new Default();

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
com.pdftools.image.Document inDoc = com.pdftools.image.Document.open(inStr)
) {
// Convert the image to a PDF document
new Converter().convert(inDoc, imageStream, profile);
} catch (Exception e) {
System.out.println("Error during image to PDF conversion: " + e.getMessage());
e.printStackTrace();
throw e;
}
}
private static void merge(MemoryStream coverStream, FileStream inputContentStream, String outPath) throws Exception {
try (
FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
DocumentAssembler docAssembler = new DocumentAssembler(outStream)) {

// Append only the first page of the cover stream
docAssembler.append(com.pdftools.pdf.Document.open(coverStream), 1, 1);
// Append the content document
docAssembler.append(com.pdftools.pdf.Document.open(inputContentStream));

// Assemble the merged document
docAssembler.assemble();
}
}
Download code sample
def add_cover_to_pdf(cover_image: str, content_pdf_path: str, output_path: str):
# Convert the image cover to a PDF (stored in memory)
with io.BytesIO() as cover_stream:
with io.FileIO(cover_image, 'rb') as image_stream:
with ImageDocument.open(image_stream) as image_document:

# Create the profile for converting the image to PDF
profile = Default()

# Convert image to PDF
converter = Converter()
converter.convert(image_document, cover_stream, profile)

# Prepare the content PDF and merge with the cover
with io.FileIO(content_pdf_path, 'rb') as content_pdf_stream:
with PdfDocument.open(content_pdf_stream) as content_pdf_document:

# Open output stream and append cover and content
with io.FileIO(output_path, 'wb+') as output_stream:
with DocumentAssembler(output_stream, None, None) as assembler:
# Append cover page (convert from memory stream to PDF)
assembler.append(PdfDocument.open(io.BytesIO(cover_stream.getvalue())), 1, 1)

# Append the content PDF
assembler.append(content_pdf_document)

# Finalize the merged document
assembler.assemble()
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

add_cover_to_pdf(cover_image, content_pdf_path, output_path)

Optimizing documents

Flatten annotations

Download code sample
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Create the profile that defines the optimization parameters.
// The MinimalFileSize profile is used to to produce a minimal file size
pProfile = (TPdfToolsOptimizationProfiles_Profile*)PdfToolsOptimizationProfiles_MinimalFileSize_New();

// Optionally the profile's parameters can be changed according to the
// requirements of your optimization process.
// Set the profile to flatten annotations (include as well Forms and Links)
TPdfToolsOptimization_RemovalOptions* pRemovalOptions =
PdfToolsOptimizationProfiles_Profile_GetRemovalOptions(pProfile);
PdfToolsOptimization_RemovalOptions_SetAnnotations(pRemovalOptions,
ePdfToolsOptimization_ConversionStrategy_Flatten);
PdfToolsOptimization_RemovalOptions_SetFormFields(pRemovalOptions,
ePdfToolsOptimization_ConversionStrategy_Flatten);
PdfToolsOptimization_RemovalOptions_SetLinks(pRemovalOptions, ePdfToolsOptimization_ConversionStrategy_Flatten);

// Optimize the document
pOptimizer = PdfToolsOptimization_Optimizer_New();
pOutDoc = PdfToolsOptimization_Optimizer_OptimizeDocument(pOptimizer, pInDoc, &outDesc, pProfile, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());
Download code sample
private static void FlattenAnnotations(string inPath, string outPath)
{
// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create the profile that defines the optimization parameters.
// The MinimalFileSize profile is used to to produce a minimal file size
var profile = new Profiles.MinimalFileSize();

// Optionally the profile's parameters can be changed according to the
// requirements of your optimization process.
profile.RemovalOptions.Annotations = ConversionStrategy.Flatten;
profile.RemovalOptions.FormFields = ConversionStrategy.Flatten;
profile.RemovalOptions.Links = ConversionStrategy.Flatten;

// Create output stream
using var outStr = File.Create(outPath);

// Optimize the document
using var outDoc = new Optimizer().OptimizeDocument(inDoc, outStr, profile);
}
Download code sample
private static void flattenAnnotations(String inPath, String outPath) throws Exception
{
// Create the profile that defines the optimization parameters.
// The MinimalFileSize profile is used to to produce a minimal file size
MinimalFileSize profile = new MinimalFileSize();

// Optionally the profile's parameters can be changed according to the
// requirements of your optimization process.
profile.getRemovalOptions().setAnnotations(ConversionStrategy.FLATTEN);
profile.getRemovalOptions().setFormFields(ConversionStrategy.FLATTEN);
profile.getRemovalOptions().setLinks(ConversionStrategy.FLATTEN);

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Optimize the document
Document outDoc = new Optimizer().optimizeDocument(inDoc, outStr, profile))
{
}
}
Download code sample
def flatten_annotations(input_path: str, output_path: str):
# Open input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:

# Create the optimization profile for minimal file size
profile = MinimalFileSize()

# Flatten annotations, form fields, and links
profile.removal_options.annotations = ConversionStrategy.FLATTEN
profile.removal_options.form_fields = ConversionStrategy.FLATTEN
profile.removal_options.links = ConversionStrategy.FLATTEN

# Create output stream
with io.FileIO(output_path, 'wb+') as output_stream:

# Optimize the document
optimizer = Optimizer()
optimizer.optimize_document(input_document, output_stream, profile)
flatten_annotations(input_path, output_path)

Optimize a PDF

Download code sample
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Create the profile that defines the optimization parameters.
// The Web profile is suitable to optimize documents for electronic document exchange.
pProfile = (TPdfToolsOptimizationProfiles_Profile*)PdfToolsOptimizationProfiles_Web_New();

// Optionally the profile's parameters can be changed according to the
// requirements of your optimization process.

// Optimize the document
pOptimizer = PdfToolsOptimization_Optimizer_New();
pOutDoc = PdfToolsOptimization_Optimizer_OptimizeDocument(pOptimizer, pInDoc, &outDesc, pProfile, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());
Download code sample
private static void Optimize(string inPath, string outPath)
{
// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create the profile that defines the optimization parameters.
// The Web profile is used to optimize documents for electronic document exchange.
var profile = new Profiles.Web();

// Optionally the profile's parameters can be changed according to the
// requirements of your optimization process.

// Create output stream
using var outStr = File.Create(outPath);

// Optimize the document
using var outDoc = new Optimizer().OptimizeDocument(inDoc, outStr, profile);
}
Download code sample
private static void optimize(String inPath, String outPath) throws Exception
{
// Create the profile that defines the optimization parameters.
// The Web profile is used to optimize documents for electronic document exchange.
Web profile = new Web();

// Optionally the profile's parameters can be changed according to the
// requirements of your optimization process.

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Optimize the document
Document outDoc = new Optimizer().optimizeDocument(inDoc, outStr, profile))
{
}
}
Download code sample
def optimize_pdf(input_path: str, output_path: str):
# Open input document
with io.FileIO(input_path, 'rb') as input_stream:
with Document.open(input_stream) as input_document:
# Create the profile that defines the optimization parameters.
# The Web profile is used to optimize documents for electronic document exchange.
profile = Web()

# Optionally the profile's parameters can be changed according to the
# requirements of your optimization process.

# Create output stream
with io.FileIO(output_path, 'wb+') as output_stream:
# Optimize the document
optimizer = Optimizer()
optimizer.optimize_document(input_document, output_stream, profile)
optimize_pdf(input_path, output_path)
Download code sample
Private Sub Optimize(inPath As String, outPath As String)
' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create the profile that defines the optimization parameters.
' The Web profile is used to optimize documents for electronic document exchange.
Dim profile = New Profiles.Web()

' Optionally the profile's parameters can be changed according to the
' requirements of your optimization process.

' Create output stream
Using outStr = File.Create(outPath)

' Optimize the document
Using outDoc = New Optimizer().OptimizeDocument(inDoc, outStr, profile)
End Using
End Using
End Using
End Using
End Sub

Powering AI applications

Convert images to an accessible PDF/A document

Download code sample
def get_alternate_text(image_path: str):
# Getting base64 representation of input image
with io.FileIO(image_path, 'rb') as image_stream:
base64_image = base64.b64encode(image_stream.read()).decode('utf-8')

# Instantiate OpenAI client and let AI create the alternate text
client = OpenAI(api_key="***insert-open-ai-api-key***")
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Write a short sentence what can be seen on the image. It shall explain to a person with impaired vision what is on the image. Write the answer in a poetic way in english."},
{
"type": "image_url",
"image_url":
{
"url": f"data:image/jpeg;base64,{base64_image}",
},
},
],
}
],
max_tokens=300,
)

return response.choices[0].message.content.strip()
def images_to_accessible_pdf(image_paths: list[str], output_file_path: str):
# Store stream descriptors and images in lists
stream_list = []
images = ImageDocumentList()

# Loop over all the image paths and store opened images into list
for input_image_path in image_paths:
image_stream = io.FileIO(input_image_path, 'rb')
stream_list.append(image_stream)
images.append(ImageDocument.open(image_stream))

# Create output stream for writing
with io.FileIO(output_file_path, 'wb+') as output_stream:
# Create the profile that defines the conversion parameters.
# The Archive profile converts images to PDF/A documents for archiving.
profile = Archive()

# Set conformance of output document to PDF/A-2a
profile.conformance = Conformance.PDF_A2_A

# For PDF/A level A, an alternate text is required for each page of the image.
# This is optional for other PDF/A levels, e.g. PDF/A-2b.
profile.language = "en"

# Set alternate texts created by AI
alternate_text_list = profile.alternate_text
for image_path in image_paths:
alternate_text = get_alternate_text(image_path)
alternate_text_list.append(alternate_text)

converter = Converter()
out_document = converter.convert_multiple(images, output_stream, profile)
if not out_document:
print(f"Error while converting images to Pdf.")
return

# Cleanup in finally block
for image in images:
image.__exit__(None, None, None)
for stream in stream_list:
stream.__exit__(None, None, None)
images_to_accessible_pdf(image_paths, output_file_path)

Sign documents

Sign a PDF and apply a visual signature appearance

Download code sample
static void AddAppearanceSignatureField(string certificateFile, string password, string appConfigFile, string inPath, string outPath)
{
// Create a session to the built-in cryptographic provider
using var session = new PdfTools.Crypto.Providers.BuiltIn.Provider();

// Create signature configuration from PFX (or P12) file
using var pfxStr = File.OpenRead(certificateFile);
var signature = session.CreateSignatureFromCertificate(pfxStr, password);

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Choose first signature field
foreach (var field in inDoc.SignatureFields)
{
if (field != null)
{
signature.FieldName = field.FieldName;
break;
}
}

// Create stream for output file
using var outStr = File.Create(outPath);

// Create appearance from either an XML or a json file
using var appStream = File.OpenRead(appConfigFile);
if (Path.GetExtension(appConfigFile) == ".xml")
signature.Appearance = Appearance.CreateFromXml(appStream);
else
signature.Appearance = Appearance.CreateFromJson(appStream);

signature.Appearance.CustomTextVariables.Add("company", "Daily Planet");

// Sign the input document
using var outDoc = new Signer().Sign(inDoc, signature, outStr);
}
Download code sample
private static void sign(String certificateFile, String password, String appConfigFile, String inPath, String outPath) throws Exception
{
try (
// Create a session to the built-in cryptographic provider
Provider session = new Provider();

// Open certificate file
FileStream pfxStr = new FileStream(certificateFile, FileStream.Mode.READ_ONLY);

// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);)
{
// Create signature configuration from PFX (or P12) file
SignatureConfiguration signature = session.createSignatureFromCertificate(pfxStr, password);

// Choose first signature field
for (int i = 0; i < inDoc.getSignatureFields().size(); i++) {
if (inDoc.getSignatureFields().get(i) != null) {
signature.setFieldName(inDoc.getSignatureFields().get(i).getFieldName());
break;
}
}

try (
// Create appearance from either an XML or a json file
FileStream appConfigStr = new FileStream(appConfigFile, FileStream.Mode.READ_ONLY))
{
if (appConfigFile.toLowerCase().endsWith(".xml"))
signature.setAppearance(Appearance.createFromXml(appConfigStr));
else
signature.setAppearance(Appearance.createFromJson(appConfigStr));

signature.getAppearance().getCustomTextVariables().put("company", "Daily Planet");

try(
// Create a stream for the output file
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Sign the input document
Document outDoc = new Signer().sign(inDoc, signature, outStr))
{
}
}
}
}
Download code sample
def add_appearance_signature_field(certificate_file: str, password: str, appearance_config_file: str, input_path: str, output_path: str):
# Create a session to the built-in cryptographic provider
with Provider() as session:
# Create signature configuration from PFX (or P12) file
with io.FileIO(certificate_file, 'rb') as pfx_str:
signature = session.create_signature_from_certificate(pfx_str, password)

# Open input document
with io.FileIO(input_path, 'rb') as input_pdf_stream:
with Document.open(input_pdf_stream) as input_pdf_document:
# Choose first signature field
for field in input_pdf_document.signature_fields:
if field:
signature.field_name = field.field_name
break

# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Create appearance configuration from either XML or JSON file
with io.FileIO(appearance_config_file, 'rb') as appearance_config_stream:
if os.path.splitext(appearance_config_file)[1].lower() == ".xml":
signature.appearance = Appearance.create_from_xml(appearance_config_stream)
else:
signature.appearance = Appearance.create_from_json(appearance_config_stream)

signature.appearance.custom_text_variables["company"] = "Daily Planet"

# Sign the input document
signer = Signer()
signer.sign(input_pdf_document, signature, output_stream)
# Sign the input document
add_appearance_signature_field(certificate_file, password, appearance_config_file, input_path, output_path)
Download code sample
Sub AddAppearanceSignatureField(certificateFile As String, password As String, appConfigFile As String, inPath As String, outPath As String)
' Create a session to the built-in cryptographic provider
Using session As New PdfTools.Crypto.Providers.BuiltIn.Provider()

' Create signature configuration from PFX (or P12) file
Using pfxStr = File.OpenRead(certificateFile)
Dim signature = session.CreateSignatureFromCertificate(pfxStr, password)

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Choose first signature field
For Each field In inDoc.SignatureFields
If field IsNot Nothing Then
signature.FieldName = field.FieldName
Exit For
End If
Next

' Create stream for output file
Using outStr = File.Create(outPath)

' Create appearance from either an XML or a JSON file
Using appStream = File.OpenRead(appConfigFile)
If Path.GetExtension(appConfigFile).ToLower() = ".xml" Then
signature.Appearance = Appearance.CreateFromXml(appStream)
Else
signature.Appearance = Appearance.CreateFromJson(appStream)
End If

signature.Appearance.CustomTextVariables.Add("company", "Daily Planet")

' Sign the input document
Using outDoc = New Signer().Sign(inDoc, signature, outStr)
End Using
End Using
End Using
End Using
End Using
End Using
End Using
End Sub

Add a signature field to a PDF

Download code sample
static void AddSignatureField(string inPath, string outPath)
{
// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create empty field appearance that is 6cm by 3cm in size
var appearance = Appearance.CreateFieldBoundingBox(Size.cm(6, 3));

// Add field to last page of document
appearance.PageNumber = inDoc.PageCount;

// Position field
appearance.Bottom = Length.cm(3);
appearance.Left = Length.cm(6.5);

// Create a signature field configuration
var field = new SignatureFieldOptions(appearance);

// Create stream for output file
using var outStr = File.Create(outPath);

// Sign the input document
using var outDoc = new Signer().AddSignatureField(inDoc, field, outStr);
}
Download code sample
private static void addSignatureField(String inPath, String outPath) throws Exception
{
try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr))
{
// Create empty field appearance that is 6cm by 3cm in size
var appearance = Appearance.createFieldBoundingBox(new Size(6, 3, Units.CENTIMETRE));

// Add field to last page of document
appearance.setPageNumber(inDoc.getPageCount());

// Position field
appearance.setBottom(new Length(3, Units.CENTIMETRE));
appearance.setLeft(new Length(6.5, Units.CENTIMETRE));

// Create a signature field configuration
var field = new SignatureFieldOptions(appearance);

try (
// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Sign the input document
Document outDoc = new Signer().addSignatureField(inDoc, field, outStr))
{
}
}
}
Download code sample
def add_signature_field(input_path: str, output_path: str):
# Open input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:
# Create empty field appearance that is 6cm by 3cm in size
appearance = Appearance.create_field_bounding_box(Size(170.08, 85.04))

# Add field to last page of document
appearance.page_number = input_document.page_count

# Position field
appearance.bottom = 85.04
appearance.left = 184.25

# Create a signature field configuration
field = SignatureFieldOptions(appearance)

# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Sign the input document
signer = Signer()
signer.add_signature_field(input_document, field, output_stream)
# Sign the input document
add_signature_field(input_path, output_path)
Download code sample
Sub AddSignatureField(inPath As String, outPath As String)
' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create empty field appearance that is 6cm by 3cm in size
Dim appearance = Sign.Appearance.CreateFieldBoundingBox(Size.cm(6, 3))

' Add field to last page of document
appearance.PageNumber = inDoc.PageCount

' Position field
appearance.Bottom = Length.cm(3)
appearance.Left = Length.cm(6.5)

' Create a signature field configuration
Dim field = New SignatureFieldOptions(appearance)

' Create stream for output file
Using outStr = File.Create(outPath)

' Sign the input document
Using outDoc = New Signer().AddSignatureField(inDoc, field, outStr)
End Using
End Using
End Using
End Using
End Sub

Add a document time-stamp to a PDF

Download code sample
static void AddTimestamp(Uri timeStampUrl, string inPath, string outPath)
{
// Create a session to the built-in cryptographic provider
using var session = new BuiltIn.Provider();
session.TimestampUrl = timeStampUrl;

// Create time-stamp configuration
var timestamp = session.CreateTimestamp();

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Add the document time-stamp
using var outDoc = new Signer().AddTimestamp(inDoc, timestamp, outStr);
}
Download code sample
private static void addTimestamp(URI timeStampUrl, String inPath, String outPath) throws Exception
{
// Create a session to the built-in cryptographic provider
try (Provider session = new Provider())
{
// Configure URL of the trusted time-stamp authority (TSA)
session.setTimestampUrl(timeStampUrl);

// Create time-stamp configuration
TimestampConfiguration timestamp = session.createTimestamp();

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Add the document time-stamp
Document outDoc = new Signer().addTimestamp(inDoc, timestamp, outStr))
{
}
}
}
Download code sample
def add_timestamp(time_stamp_url: str, input_path: str, output_path: str):
# Create a session to the built-in cryptographic provider
with Provider() as session:
session.timestamp_url = time_stamp_url

# Create time-stamp configuration
timestamp = session.create_timestamp()

# Open input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:

# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:

# Add the document time-stamp
signer = Signer()
signer.add_timestamp(input_document, timestamp, output_stream)
# Optional: Set your proxy configuration
# Sdk.Proxy = new Uri("http://myproxy:8080");

# Add a document time-stamp to a PDF
add_timestamp(time_stamp_url, input_path, output_path)
Download code sample
Sub AddTimestamp(timeStampUrl As Uri, inPath As String, outPath As String)
' Create a session to the built-in cryptographic provider
Using session As New BuiltIn.Provider()
session.TimestampUrl = timeStampUrl

' Create time-stamp configuration
Dim timestamp = session.CreateTimestamp()

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Add the document time-stamp
Using outDoc = New Signer().AddTimestamp(inDoc, timestamp, outStr)
End Using
End Using
End Using
End Using
End Using
End Sub

Certify a PDF

Download code sample
static void Certify(string certificateFile, string password, string inPath, string outPath)
{
// Create a session to the built-in cryptographic provider
using var session = new BuiltIn.Provider();

// Create signature configuration from PFX (or P12) file
using var pfxStr = File.OpenRead(certificateFile);
var signature = session.CreateSignatureFromCertificate(pfxStr, password);

// Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument;

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Add a document certification (MDP) signature
// Optionally, the access permissions can be set.
using var outDoc = new Signer().Certify(inDoc, signature, outStr);
}
Download code sample
private static void certify(String certificateFile, String password, String inPath, String outPath) throws Exception
{
try (
// Create a session to the built-in cryptographic provider
Provider session = new Provider();

// Open certificate file
FileStream pfxStr = new FileStream(certificateFile, FileStream.Mode.READ_ONLY))
{
// Create signature configuration from PFX (or P12) file
SignatureConfiguration signature = session.createSignatureFromCertificate(pfxStr, password);

// Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.setValidationInformation(com.pdftools.crypto.ValidationInformation.EMBED_IN_DOCUMENT);

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Add a document certification (MDP) signature
// Optionally, the access permissions can be set.
Document outDoc = new Signer().certify(inDoc, signature, outStr))
{
}
}
}
Download code sample
def certify_document(certificate_file: str, password: str, input_path: str, output_path: str):
# Create a session to the built-in cryptographic provider
with Provider() as session:
with io.FileIO(certificate_file, 'rb') as pfx_stream:
# Create signature configuration from PFX (or P12) file
signature = session.create_signature_from_certificate(pfx_stream, password)

# Embed validation information to enable the long-term validation (LTV) of the signature
signature.validation_information = ValidationInformation.EMBED_IN_DOCUMENT

# Open input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:

# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Certify the document with the MDP signature
signer = Signer()
signer.certify(input_document, signature, output_stream)
# Certify a PDF document
certify_document(certificate_file, password, input_path, output_path)
Download code sample
Sub Certify(certificateFile As String, password As String, inPath As String, outPath As String)
' Create a session to the built-in cryptographic provider
Using session As New BuiltIn.Provider()

' Create signature configuration from PFX (or P12) file
Using pfxStr = File.OpenRead(certificateFile)
Dim signature = session.CreateSignatureFromCertificate(pfxStr, password)

' Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Add a document certification (MDP) signature
' Optionally, the access permissions can be set.
Using outDoc = New Signer().Certify(inDoc, signature, outStr)
End Using
End Using
End Using
End Using
End Using
End Using
End Sub

Sign a PDF using a software-based certificate file

Download code sample
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrorBuff, PdfTools_GetLastError());

// Create output stream for writing
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
TPdfToolsSys_StreamDescriptor outDesc;
PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);

// Create a session to the built-in cryptographic provider
pSession = PdfToolsCryptoProvidersBuiltIn_Provider_New();

// Create signature configuration from PFX (or P12) file
pCertificateFileStream = _tfopen(szCertificateFile, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
pCertificateFileStream, _T("Failed to open the certificate file \"%s\" for reading.\n"), szCertificateFile);
TPdfToolsSys_StreamDescriptor certificateFileDesc;
PdfToolsSysCreateFILEStreamDescriptor(&certificateFileDesc, pCertificateFileStream, 0);
pSignatureConfiguration = PdfToolsCryptoProvidersBuiltIn_Provider_CreateSignatureFromCertificate(
pSession, &certificateFileDesc, szPassword);

// Embed validation information to enable the long term validation (LTV) of the signature (default)
PdfToolsCryptoProvidersBuiltIn_SignatureConfiguration_SetValidationInformation(
pSignatureConfiguration, ePdfToolsCrypto_ValidationInformation_EmbedInDocument);

// Sign the input document
pSigner = PdfToolsSign_Signer_New();
pOutDoc = PdfToolsSign_Signer_Sign(pSigner, pInDoc, pSignatureConfiguration, &outDesc, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
PdfTools_GetLastError());
Download code sample
static void Sign(string certificateFile, string password, string inPath, string outPath)
{
// Create a session to the built-in cryptographic provider
using var session = new BuiltIn.Provider();

// Create signature configuration from PFX (or P12) file
using var pfxStr = File.OpenRead(certificateFile);
var signature = session.CreateSignatureFromCertificate(pfxStr, password);

// Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument;

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Sign the input document
using var outDoc = new Signer().Sign(inDoc, signature, outStr);
}
Download code sample
private static void sign(String certificateFile, String password, String inPath, String outPath) throws Exception
{
try (
// Create a session to the built-in cryptographic provider
Provider session = new Provider();

// Open certificate file
FileStream pfxStr = new FileStream(certificateFile, FileStream.Mode.READ_ONLY))
{
// Create signature configuration from PFX (or P12) file
SignatureConfiguration signature = session.createSignatureFromCertificate(pfxStr, password);

// Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.setValidationInformation(com.pdftools.crypto.ValidationInformation.EMBED_IN_DOCUMENT);

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create a stream for the output file
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Sign the input document
Document outDoc = new Signer().sign(inDoc, signature, outStr))
{
}
}
}
Download code sample
def sign(certificate_file: str, password: str, input_path: str, output_path: str):
# Create a session to the built-in cryptographic provider
with Provider() as session:
with io.FileIO(certificate_file, 'rb') as pfx_str:
# Create signature configuration from PFX (or P12) file
signature = session.create_signature_from_certificate(pfx_str, password)

# Embed validation information to enable long-term validation (LTV) of the signature
signature.validation_information = ValidationInformation.EMBED_IN_DOCUMENT

signature.appearance = Appearance.create_field_bounding_box(Size(width=200, height=300))
signature.appearance.page_number = 1

# Open input document
with io.FileIO(input_path, 'rb') as input_pdf_stream:
with Document.open(input_pdf_stream) as input_pdf_document:
# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Sign the input document
signer = Signer()
signer.sign(input_pdf_document, signature, output_stream)
# Sign a PDF document
sign(certificate_file, password, input_path, output_path)
Download code sample
Sub Sign(certificateFile As String, password As String, inPath As String, outPath As String)
' Create a session to the built-in cryptographic provider
Using session As New BuiltIn.Provider()

' Create signature configuration from PFX (or P12) file
Using pfxStr = File.OpenRead(certificateFile)
Dim signature = session.CreateSignatureFromCertificate(pfxStr, password)

' Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Sign the input document
Using outDoc = New Signer().Sign(inDoc, signature, outStr)
End Using
End Using
End Using
End Using
End Using
End Using
End Sub

Add a document time-stamp to a PDF using the GlobalSign Digital Signing Service

Download code sample
// Configure the SSL client certificate to connect to the service
var httpClientHandler = new HttpClientHandler();
using (var sslClientCert = File.OpenRead(@"C:\path\to\clientcert.cer"))
using (var sslClientKey = File.OpenRead(@"C:\path\to\privateKey.key"))
httpClientHandler.SetClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***");

// Connect to the GlobalSign Digital Signing Service
using var session = new GlobalSignDss.Session(new Uri("https://emea.api.dss.globalsign.com:8443"), "***insert api_key***", "***insert api_secret***", httpClientHandler);

// Add a document time-stamp to a PDF
AddTimestamp(session, inPath, outPath);
static void AddTimestamp(GlobalSignDss.Session session, string inPath, string outPath)
{
// Create time-stamp configuration
var timestamp = session.CreateTimestamp();

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Add the document time-stamp
using var outDoc = new Signer().AddTimestamp(inDoc, timestamp, outStr);
}
Download code sample
// Configure the SSL client certificate to connect to the service
HttpClientHandler httpClientHandler = new HttpClientHandler();
try (
FileStream sslClientCert = new FileStream("C:/path/to/clientcert.cer", FileStream.Mode.READ_ONLY);
FileStream sslClientKey = new FileStream("C:/path/to/privateKey.key", FileStream.Mode.READ_ONLY))
{
httpClientHandler.setClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***");
}

// Connect to the GlobalSign Digital Signing Service
try (Session session = new Session(new URI("https://emea.api.dss.globalsign.com:8443"),
"***insert api_key***", "***insert api_secret***",
httpClientHandler))
{
// Add a document time-stamp to a PDF
addTimestamp(session, inPath, outPath);
}
private static void addTimestamp(Session session, String inPath, String outPath) throws Exception
{
// Create time-stamp configuration
TimestampConfiguration timestamp = session.createTimestamp();

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Add the document time-stamp
Document outDoc = new Signer().addTimestamp(inDoc, timestamp, outStr))
{
}
}
Download code sample
def add_timestamp(session: Session, input_path: str, output_path: str):
# Create time-stamp configuration
timestamp = session.create_timestamp()

# Open input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:

# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:

# Add the document time-stamp
signer = Signer()
signer.add_timestamp(input_document, timestamp, output_stream)
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

# Configure the SSL client certificate to connect to the service
http_client_handler = HttpClientHandler()
with io.FileIO("***insert .cer path***", 'rb') as cert_stream:
with io.FileIO("***insert .key path***", 'rb') as key_stream:
http_client_handler.set_client_certificate_and_key(cert_stream, key_stream, "***insert password***")

# Connect to the GlobalSign DSS service
with Session("https://emea.api.dss.globalsign.com:8443", "***insert api_key***", "***insert api_secret***", http_client_handler) as session:
# Add a document time-stamp to a PDF
add_timestamp(session, input_path, output_path)
Download code sample
' Configure the SSL client certificate to connect to the service
Dim httpClientHandler = New HttpClientHandler()
Using sslClientCert = File.OpenRead("C:\path\to\clientcert.cer")
Using sslClientKey = File.OpenRead("C:\path\to\privateKey.key")
httpClientHandler.SetClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***")
End Using
End Using

' Connect to the GlobalSign Digital Signing Service
Using session = New GlobalSignDss.Session(New Uri("https://emea.api.dss.globalsign.com:8443"), "***insert api_key***", "***insert api_secret***", httpClientHandler)

' Add a document time-stamp to a PDF
AddTimestamp(session, inPath, outPath)
End Using
Sub AddTimestamp(session As GlobalSignDss.Session, inPath As String, outPath As String)
' Create time-stamp configuration
Dim timestamp = session.CreateTimestamp()

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Add the document time-stamp
Using outDoc = New Signer().AddTimestamp(inDoc, timestamp, outStr)
End Using
End Using
End Using
End Using
End Sub

Sign a PDF using the GlobalSign Digital Signing Service

Download code sample
// Configure the SSL client certificate to connect to the service
var httpClientHandler = new HttpClientHandler();
using (var sslClientCert = File.OpenRead(@"C:\path\to\clientcert.cer"))
using (var sslClientKey = File.OpenRead(@"C:\path\to\privateKey.key"))
httpClientHandler.SetClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***");

// Connect to the GlobalSign Digital Signing Service
using var session = new GlobalSignDss.Session(new Uri("https://emea.api.dss.globalsign.com:8443"), "***insert api_key***", "***insert api_secret***", httpClientHandler);

// Sign a PDF document
Sign(session, commonName, inPath, outPath);
static void Sign(GlobalSignDss.Session session, string commonName, string inPath, string outPath)
{
// Create a signing certificate for an account with a dynamic identity
var identity = JsonSerializer.Serialize(new { subject_dn = new { common_name = commonName } });
var signature = session.CreateSignatureForDynamicIdentity(identity);

// Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument;

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Sign the document
using var outDoc = new Signer().Sign(inDoc, signature, outStr);
}
Download code sample
// Configure the SSL client certificate to connect to the service
HttpClientHandler httpClientHandler = new HttpClientHandler();
try (
FileStream sslClientCert = new FileStream("C:/path/to/clientcert.cer", FileStream.Mode.READ_ONLY);
FileStream sslClientKey = new FileStream("C:/path/to/privateKey.key", FileStream.Mode.READ_ONLY))
{
httpClientHandler.setClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***");
}

// Connect to the GlobalSign Digital Signing Service
try (Session session = new Session(new URI("https://emea.api.dss.globalsign.com:8443"),
"***insert api_key***", "***insert api_secret***",
httpClientHandler))
{
// Sign a PDF document
sign(session, commonName, inPath, outPath);
}
private static void sign(Session session, String commonName, String inPath, String outPath) throws Exception
{
// Create a signing certificate for an account with a dynamic identity
// This can be re-used to sign multiple documents
SignatureConfiguration signature = session.createSignatureForDynamicIdentity(String.format("{ \"subject_dn\" : { \"common_name\" : \"%s\" } }", commonName));

// Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.setValidationInformation(ValidationInformation.EMBED_IN_DOCUMENT);

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Sign the input document
Document outDoc = new Signer().sign(inDoc, signature, outStr))
{
}
}
Download code sample
def sign(session: Session, common_name: str, input_path: str, output_path: str):
# Create a signing certificate for an account with a dynamic identity
identity = json.dumps({"subject_dn": {"common_name": common_name}})
signature = session.create_signature_for_dynamic_identity(identity)

# Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.validation_information = ValidationInformation.EMBED_IN_DOCUMENT

# Open input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:

# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:

# Sign the document
signer = Signer()
signer.sign(input_document, signature, output_stream)
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

# Configure the SSL client certificate to connect to the service
http_client_handler = HttpClientHandler()
with io.FileIO("***insert .cer path***", 'rb') as cert_stream:
with io.FileIO("***insert .key path***", 'rb') as key_stream:
http_client_handler.set_client_certificate_and_key(cert_stream, key_stream, "***insert password***")

# Connect to the GlobalSign DSS service
with Session("https://emea.api.dss.globalsign.com:8443", "***insert api_key***", "***insert api_secret***", http_client_handler) as session:
# Sign a PDF document
sign(session, common_name, input_path, output_path)
Download code sample
' Configure the SSL client certificate to connect to the service
Dim httpClientHandler = New HttpClientHandler()
Using sslClientCert = File.OpenRead("C:\path\to\clientcert.cer")
Using sslClientKey = File.OpenRead("C:\path\to\privateKey.key")
httpClientHandler.SetClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***")
End Using
End Using

' Connect to the GlobalSign Digital Signing Service
Using session = New GlobalSignDss.Session(New Uri("https://emea.api.dss.globalsign.com:8443"), "***insert api_key***", "***insert api_secret***", httpClientHandler)

' Sign a PDF document
Sign(session, commonName, inPath, outPath)
End Using
Sub Sign(session As GlobalSignDss.Session, commonName As String, inPath As String, outPath As String)
' Create a signing certificate for an account with a dynamic identity
Dim identity = JsonSerializer.Serialize(New With {.subject_dn = New With {.common_name = commonName}})
Dim signature = session.CreateSignatureForDynamicIdentity(identity)

' Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Sign the document
Using outDoc = New Signer().Sign(inDoc, signature, outStr)
End Using
End Using
End Using
End Using
End Sub

Sign a PDF using a PKCS#11 device

Download code sample
// Load the PKCS#11 driver module (middleware)
// The module can only be loaded once in the application.
using var module = Pkcs11.Module.Load(pkcs11Library);

// Create a session to the cryptographic device and log in
// with the password (pin)
// Use Devices[i] if you have more than one device installed instead of Devices.GetSingle()
using var session = module.Devices.GetSingle().CreateSession(password);

// Sign a PDF document
Sign(session, certificate, inPath, outPath);
static void Sign(Pkcs11.Session session, string certificate, string inPath, string outPath)
{
// Create the signature configuration
// This can be re-used to sign multiple documents
var signature = session.CreateSignatureFromName(certificate);

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Sign the input document
using var outDoc = new Signer().Sign(inDoc, signature, outStr);
}
Download code sample
try (
// Load the PKCS#11 driver module (middleware)
// The module can only be loaded once in the application.
Module module = Module.load(pkcs11Library);

// Create a session to the cryptographic device and log in
// with the password (pin)
Session session = module.getDevices().getSingle().createSession(password))
{
// Sign a PDF document
sign(session, certificate, inPath, outPath);
}
private static void sign(Session session, String certificate, String inPath, String outPath) throws Exception
{
// Create the signature configuration
// This can be re-used to sign multiple documents
SignatureConfiguration signature = session.createSignatureFromName(certificate);

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Sign the input document
Document outDoc = new Signer().sign(inDoc, signature, outStr))
{
}
}
Download code sample
def sign(session: Session, certificate: str, input_path: str, output_path: str):
# Create the signature configuration for the certificate
signature = session.create_signature_from_name(certificate)

# Open input document
with io.FileIO(input_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:

# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:

# Sign the input document
signer = Signer()
signer.sign(input_document, signature, output_stream)
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

# Load the PKCS#11 driver module (middleware)
# The module can only be loaded once in the application.
with Module.load(pkcs11_library) as module:

# Create a session to the cryptographic device and log in with the password (pin)
# Use devices[i] if you have more than one device installed instead of devices.get_single()
with module.devices.get_single().create_session(password) as session:
# Sign a PDF document
sign(session, certificate, input_path, output_path)
Download code sample
' Load the PKCS#11 driver module (middleware)
' The module can only be loaded once in the application.
Using [module] = Pkcs11.Module.Load(pkcs11Library)

' Create a session to the cryptographic device and log in
' with the password (pin)
Using session = [module].Devices.GetSingle().CreateSession(password)

' Sign a PDF document
Sign(session, certificate, inPath, outPath)
End Using
End Using
Sub Sign(session As Pkcs11.Session, certificate As String, inPath As String, outPath As String)
' Create the signature configuration
' This can be re-used to sign multiple documents
Dim signature = session.CreateSignatureFromName(certificate)

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Sign the input document
Using outDoc = New Signer().Sign(inDoc, signature, outStr)
End Using
End Using
End Using
End Using
End Sub

Validate the signatures contained in an input document

Download code sample

// Helper functions to print signature validation details
static int Validate(string inputFile, string certDir)
{
// Use the default validation profile as a base for further settings
var profile = new Default();

// For offline operation, build a custom trust list from the file system
// and disable external revocation checks
if (certDir != null && certDir.Length != 0)
{
Console.WriteLine("Using 'offline' validation mode with custom trust list.");
Console.WriteLine();

// create a CustomTrustList to hold the certificates
var ctl = new CustomTrustList();

// Iterate through files in the certificate directory and add certificates
// to the custom trust list
if (Directory.Exists(certDir))
{
var directoryListing = Directory.EnumerateFiles(certDir);
foreach (string fileName in directoryListing)
{
try
{
using var certStr = File.OpenRead(fileName);

if (fileName.EndsWith(".cer") || fileName.EndsWith(".pem"))
{
ctl.AddCertificates(certStr);
}
else if (fileName.EndsWith(".p12") || fileName.EndsWith(".pfx"))
{
// If a password is required, use addArchive(certStr, password).
ctl.AddArchive(certStr);
}
}
catch (Exception e)
{
Console.WriteLine("Could not add certificate '" + fileName + "' to custom trust list: " + e.Message);
}
}
}
else
{
// Handle the case where dir is not a directory
Console.WriteLine("Directory " + certDir + " is missing. No certificates were added to the custom trust list.");
}
Console.WriteLine();

// Assign the custom trust list to the validation profile
profile.CustomTrustList = ctl;

// Allow validation from embedded file sources and the custom trust list
var vo = profile.ValidationOptions;
vo.TimeSource = TimeSource.ProofOfExistence | TimeSource.ExpiredTimeStamp | TimeSource.SignatureTime;
vo.CertificateSources = DataSource.EmbedInSignature | DataSource.EmbedInDocument | DataSource.CustomTrustList;

// Disable revocation checks.
profile.SigningCertTrustConstraints.RevocationCheckPolicy = RevocationCheckPolicy.NoCheck;
profile.TimeStampTrustConstraints.RevocationCheckPolicy = RevocationCheckPolicy.NoCheck;
}

// Validate ALL signatures in the document (not only the latest)
var signatureSelector = SignatureSelector.All;

// Create the validator object and event listeners
var validator = new Validator();
validator.Constraint += (s, e) =>
{
Console.WriteLine(" - " + e.Signature.Name + (e.DataPart.Length > 0 ? (": " + e.DataPart) : "") + ": " +
ConstraintToString(e.Indication, e.SubIndication, e.Message));
};

try
{
using var inStr = File.OpenRead(inputFile);
// Open input document
// If a password is required, use Open(inStr, password)
using var document = Document.Open(inStr);

// Run the validate method passing the document, profile and selector
Console.WriteLine("Validation Constraints");
var results = validator.Validate(document, profile, signatureSelector);

Console.WriteLine();
Console.WriteLine("Signatures validated: " + results.Count);
Console.WriteLine();

// Print results
foreach (var result in results)
{
var field = result.SignatureField;
Console.WriteLine(field.FieldName + " of " + field.Name);
try
{
Console.WriteLine(" - Revision : " + (field.Revision.IsLatest ? "latest" : "intermediate"));
}
catch (Exception ex)
{
Console.WriteLine("Unable to validate document Revision: " + ex.Message);
}

PrintContent(result.SignatureContent, result.SignatureField.IsFullRevisionCovered);
Console.WriteLine();
}

return 0;
}
catch (Exception ex)
{
Console.WriteLine("Unable to validate file: " + ex.Message);
return 5;
}
}
private static void PrintContent(SignatureContent content, bool? isFullRevisionCovered)
{
if (content != null)
{
Console.WriteLine(" - Validity : " + ConstraintToString(content.Validity, isFullRevisionCovered));
switch (content)
{
case UnsupportedSignatureContent:
break;
case CmsSignatureContent signature:
{
Console.WriteLine(" - Validation: " + signature.ValidationTime + " from " + signature.ValidationTimeSource);
Console.WriteLine(" - Hash : " + signature.HashAlgorithm);
Console.WriteLine(" - Signing Cert");
PrintContent(signature.SigningCertificate);
Console.WriteLine(" - Chain");
foreach (var cert in signature.CertificateChain)
{
Console.WriteLine(" - Issuer Cert " + (signature.CertificateChain.IndexOf(cert) + 1));
PrintContent(cert);
}
Console.WriteLine(" - Chain : " + (signature.CertificateChain.IsComplete ? "complete" : "incomplete") + " chain");
Console.WriteLine(" Time-Stamp");
PrintContent(signature.TimeStamp, null);
break;
}
case TimeStampContent timeStamp:
{
Console.WriteLine(" - Validation: " + timeStamp.ValidationTime + " from " + timeStamp.ValidationTimeSource);
Console.WriteLine(" - Hash : " + timeStamp.HashAlgorithm);
Console.WriteLine(" - Time : " + timeStamp.Date);
Console.WriteLine(" - Signing Cert");
PrintContent(timeStamp.SigningCertificate);
Console.WriteLine(" - Chain");
foreach (var cert in timeStamp.CertificateChain)
{
Console.WriteLine(" - Issuer Cert " + (timeStamp.CertificateChain.IndexOf(cert) + 1));
PrintContent(cert);
}
Console.WriteLine(" - Chain : " + (timeStamp.CertificateChain.IsComplete ? "complete" : "incomplete") + " chain");
break;
}
default:
Console.WriteLine("Unsupported signature content type " + content.GetType().Name);
break;
}
}
else
{
Console.WriteLine(" - null");
}
}
private static void PrintContent(Certificate cert)
{
if(cert != null)
{
Console.WriteLine(" - Subject : " + cert.SubjectName);
Console.WriteLine(" - Issuer : " + cert.IssuerName);
Console.WriteLine(" - Validity : " + cert.NotBefore + " - " + cert.NotAfter);
try
{
Console.WriteLine(" - Fingerprint: " + FormatSha1Digest(new BigInteger(SHA1.Create().ComputeHash(cert.RawData)).ToByteArray(), "-"));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine(" - Source : " + cert.Source);
Console.WriteLine(" - Validity : " + ConstraintToString(cert.Validity, null));
}
else
{
Console.WriteLine(" - null");
}
}
private static String ConstraintToString(ConstraintResult constraint, bool? isFullRevisionCovered)
{
return ConstraintToString(constraint.Indication, constraint.SubIndication, constraint.Message, isFullRevisionCovered);
}
private static string ConstraintToString(Indication indication, SubIndication subIndication, string message, bool? isFullRevisionCovered = null)
{
if (isFullRevisionCovered is null || isFullRevisionCovered.Value)
{
return (indication == Indication.Valid ? "" : indication == Indication.Indeterminate ? "?" : "!") + subIndication + " " + message;
}
string byteRangeInvalid = "!Invalid signature byte range.";
return indication == Indication.Valid ? byteRangeInvalid : $"{byteRangeInvalid} {subIndication} {message}";
}
// Helper function to generate a delimited SHA-1 digest string
private static String FormatSha1Digest(byte[] bytes, String delimiter)
{
var result = new StringBuilder();
foreach (byte aByte in bytes)
{
int number = (int)aByte & 0xff;
String hex = number.ToString("X2");
result.Append(hex.ToUpper() + delimiter);
}
return result.ToString().Substring(0, result.Length - delimiter.Length);
}
Download code sample

// Helper functions to print signature validation details
private static int validate(String inputFile, String certDir)
{
// Use the default validation profile as a base for further settings
Profile profile = new Default();

// For offline operation, build a custom trust list from the file system
// and disable external revocation checks
if (certDir != null && !certDir.isEmpty())
{
System.out.println("Using 'offline' validation mode with custom trust list.");
System.out.println();

// create a CustomTrustList to hold the certificates
CustomTrustList ctl = new CustomTrustList();

// Iterate through files in the certificate directory and add certificates
// to the custom trust list
File dir = new File(certDir);
File[] directoryListing = dir.listFiles();
if (directoryListing != null)
{
for (File child : directoryListing)
{
String fileName = child.getName();
try (
FileStream certStr = new FileStream(child.getPath(), FileStream.Mode.READ_ONLY))
{
if (fileName.endsWith(".cer") || fileName.endsWith(".pem"))
{
ctl.addCertificates(certStr);
}
else if (fileName.endsWith(".p12") || fileName.endsWith(".pfx"))
{
// If a password is required, use addArchive(certStr, password).
ctl.addArchive(certStr);
}
}
catch (Exception e)
{
System.out.println("Could not add certificate '" + child.getName() + "' to custom trust list: " + e.getMessage());
}
}
}
else
{
// Handle the case where dir is not a directory
System.out.println("Directory " + certDir + " is missing. No certificates were added to the custom trust list.");
}
System.out.println();

// Assign the custom trust list to the validation profile
profile.setCustomTrustList(ctl);

// Allow validation from embedded file sources and the custom trust list
ValidationOptions vo = profile.getValidationOptions();
vo.setTimeSource(EnumSet.of(TimeSource.PROOF_OF_EXISTENCE, TimeSource.EXPIRED_TIME_STAMP, TimeSource.SIGNATURE_TIME));
vo.setCertificateSources(EnumSet.of(DataSource.EMBED_IN_SIGNATURE, DataSource.EMBED_IN_DOCUMENT, DataSource.CUSTOM_TRUST_LIST));

// Disable revocation checks.
profile.getSigningCertTrustConstraints().setRevocationCheckPolicy(RevocationCheckPolicy.NO_CHECK);
profile.getTimeStampTrustConstraints().setRevocationCheckPolicy(RevocationCheckPolicy.NO_CHECK);
}

// Validate ALL signatures in the document (not only the latest)
SignatureSelector signatureSelector = SignatureSelector.ALL;

// Create the validator object and event listeners
Validator validator = new Validator();
validator.addConstraintListener(e -> {
System.out.println(" - " + e.getSignature().getName() + (e.getDataPart().length() > 0 ? (": " + e.getDataPart()) : "") + ": " +
constraintToString(e.getIndication(), e.getSubIndication(), e.getMessage(), true));
});

try (
FileStream inStr = new FileStream(inputFile, FileStream.Mode.READ_ONLY);
// Open input document
// If a password is required, use open(inStr, password)
Document document = Document.open(inStr);
)
{
// Run the validate method passing the document, profile and selector
System.out.println("Validation Constraints");
ValidationResults results = validator.validate(document, profile, signatureSelector);

System.out.println();
System.out.println("Signatures validated: " + results.size());
System.out.println();

// Print results
results.forEach(result -> {
SignedSignatureField field = result.getSignatureField();
System.out.println(field.getFieldName() + " of " + field.getName());
try
{
System.out.println(" - Revision : " + (field.getRevision().getIsLatest() ? "latest" : "intermediate"));
}
catch (Exception ex)
{
System.out.println("Unable to validate document Revision: " + ex.getMessage());
}

printContent(result.getSignatureContent(), result.getSignatureField().getFullRevisionCovered());
System.out.println();
});

return 0;
}
catch (Exception ex)
{
System.out.println("Unable to validate file: " + ex.getMessage());
return 5;
}
}
private static void printContent(SignatureContent content, Boolean isFullRevisionCovered)
{
if (content != null)
{
System.out.println(" - Validity : " + constraintToString(content.getValidity(), isFullRevisionCovered));
switch (content.getClass().getSimpleName())
{
case "UnsupportedSignatureContent":
break;
case "CmsSignatureContent":
{
CmsSignatureContent signature = (CmsSignatureContent)content;
System.out.println(" - Validation: " + signature.getValidationTime() + " from " + signature.getValidationTimeSource());
System.out.println(" - Hash : " + signature.getHashAlgorithm());
System.out.println(" - Signing Cert");
printContent(signature.getSigningCertificate());
System.out.println(" - Chain");
signature.getCertificateChain().forEach(cert -> {
System.out.println(" - Issuer Cert " + (signature.getCertificateChain().indexOf(cert) + 1));
printContent(cert);
});
System.out.println(" - Chain : " + (signature.getCertificateChain().getIsComplete() ? "complete" : "incomplete") + " chain");
System.out.println(" Time-Stamp");
printContent(signature.getTimeStamp(), true);
break;
}
case "TimeStampContent":
{
TimeStampContent timeStamp = (TimeStampContent)content;
System.out.println(" - Validation: " + timeStamp.getValidationTime() + " from " + timeStamp.getValidationTimeSource());
System.out.println(" - Hash : " + timeStamp.getHashAlgorithm());
System.out.println(" - Time : " + timeStamp.getDate());
System.out.println(" - Signing Cert");
printContent(timeStamp.getSigningCertificate());
System.out.println(" - Chain");
timeStamp.getCertificateChain().forEach(cert -> {
System.out.println(" - Issuer Cert " + (timeStamp.getCertificateChain().indexOf(cert) + 1));
printContent(cert);
});
System.out.println(" - Chain : " + (timeStamp.getCertificateChain().getIsComplete() ? "complete" : "incomplete") + " chain");
break;
}
default:
System.out.println("Unsupported signature content type " + content.getClass().getName());
break;
}
}
else
{
System.out.println(" - null");
}
}
private static void printContent(Certificate cert)
{
if(cert != null)
{
System.out.println(" - Subject : " + cert.getSubjectName());
System.out.println(" - Issuer : " + cert.getIssuerName());
System.out.println(" - Validity : " + cert.getNotBefore() + " - " + cert.getNotAfter());
try {
System.out.println(" - Fingerprint: " + formatSha1Digest(new java.math.BigInteger(1, (MessageDigest.getInstance("SHA-1").digest(cert.getRawData()))).toByteArray(), "-"));
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
System.out.println(" - Source : " + cert.getSource());
System.out.println(" - Validity : " + constraintToString(cert.getValidity(), true));
}
else
{
System.out.println(" - null");
}
}
private static String constraintToString(ConstraintResult constraint, Boolean isFullRevisionCovered)
{
return constraintToString(constraint.getIndication(), constraint.getSubIndication(), constraint.getMessage(), isFullRevisionCovered);
}
private static String constraintToString(Indication indication, SubIndication subIndication, String message, Boolean isFullRevisionCovered)
{
if (isFullRevisionCovered == null || isFullRevisionCovered)
{
return (indication == Indication.VALID ? "" : (indication == Indication.INDETERMINATE ? "?" : "!")) + "" +
subIndication + " " +
message;
}

String byteRangeInvalid = "!Invalid signature byte range.";
if (indication == Indication.VALID)
return byteRangeInvalid;
else
return byteRangeInvalid + " " + subIndication + " " + message;
}
// Helper function to generate a delimited SHA-1 digest string
private static String formatSha1Digest(byte[] bytes, String delimiter) {
StringBuilder result = new StringBuilder();
for (byte aByte : bytes) {
int decimal = (int) aByte & 0xff;
String hex = Integer.toHexString(decimal);
if (hex.length() % 2 == 1)
hex = "0" + hex;
result.append(hex.toUpperCase() + delimiter);
}
return result.substring(0, result.length() - delimiter.length());
}
Download code sample
def constraint_to_string(indication: Indication, sub_indication: str, message: str, is_full_revision_covered: bool = None):
# Handle byte range validation if is_full_revision_covered is provided
if is_full_revision_covered is None or is_full_revision_covered:
indication_str = (
"" if indication == Indication.VALID else
"?" if indication == Indication.INDETERMINATE else
"!"
)
return f"{indication_str}{sub_indication} {message}"

byte_range_invalid = "!Invalid signature byte range."
if indication == Indication.VALID:
return byte_range_invalid
else:
return f"{byte_range_invalid} {sub_indication} {message}"
def format_sha1_digest(fingerprint: str, delimiter: str):
return delimiter.join(fingerprint[i:i+2] for i in range(0, len(fingerprint), 2))
def print_certificate(cert: Certificate):
if cert is not None:
print(f" - Subject : {cert.subject_name}")
print(f" - Issuer : {cert.issuer_name}")
print(f" - Validity : {cert.not_before} - {cert.not_after}")
try:
# Convert the list of integers to bytes
raw_data_bytes = bytes(cert.raw_data)

# Fingerprint calculation using hashlib
fingerprint = hashlib.sha1(raw_data_bytes).hexdigest().upper()
print(f" - Fingerprint: {format_sha1_digest(fingerprint, '-')}")
except Exception as ex:
print(str(ex))
# Extract and print the individual DataSource names
sources = [source.name for source in DataSource if source in cert.source]
print(f" - Source : {', '.join(sources)}")
print(f" - Validity : {constraint_to_string(cert.validity.indication, cert.validity.sub_indication.name, cert.validity.message)}")
else:
print(" - null")
def print_signature_content(content: SignatureContent, is_full_revision_covered: bool = None):
if content is not None:
print(f" - Validity : {constraint_to_string(content.validity.indication, content.validity.sub_indication.name, content.validity.message, is_full_revision_covered)}")

if isinstance(content, UnsupportedSignatureContent):
pass # No action for unsupported content
elif isinstance(content, CmsSignatureContent):
print(f" - Validation: {content.validation_time} from {content.validation_time_source.name}")
print(f" - Hash : {content.hash_algorithm.name}")
print(" - Signing Cert")
print_certificate(content.signing_certificate)
print(" - Chain")
for index, cert in enumerate(content.certificate_chain, start=1):
print(f" - Issuer Cert {index}")
print_certificate(cert)
print(f" - Chain : {'complete' if content.certificate_chain.is_complete else 'incomplete'} chain")
print(" Time-Stamp")
print_signature_content(content.time_stamp)
elif isinstance(content, TimeStampContent):
print(f" - Validation: {content.validation_time} from {content.validation_time_source.name}")
print(f" - Hash : {content.hash_algorithm.name}")
print(f" - Time : {content.date}")
print(" - Signing Cert")
print_certificate(content.signing_certificate)
print(" - Chain")
for index, cert in enumerate(content.certificate_chain, start=1):
print(f" - Issuer Cert {index}")
print_certificate(cert)
print(f" - Chain : {'complete' if content.certificate_chain.is_complete else 'incomplete'} chain")
else:
print(f"Unsupported signature content type {str(type(content))}")
else:
print(" - null")
def on_constraint_event(message: str, indication: Indication, sub_indication: SubIndication, signature: DocumentSignature, data_part: str):
print(f" - {signature.name}" + (f": {data_part}" if len(data_part) > 0 else "") + ": " +
constraint_to_string(indication, sub_indication.name, message))
def validate(input_file: str, cert_dir: str):
# Use the default validation profile as a base for further settings
profile = Default()

# For offline operation, build a custom trust list from the file system and disable external revocation checks
if cert_dir:
print("Using 'offline' validation mode with custom trust list.")
print()

# create a CustomTrustList to hold the certificates
ctl = CustomTrustList()

# Iterate through files in the certificate directory and add certificates to the custom trust list
if os.path.isdir(cert_dir):
for file_name in os.listdir(cert_dir):
try:
with io.FileIO(os.path.join(cert_dir, file_name), 'rb') as cert_stream:
if file_name.endswith(".cer") or file_name.endswith(".pem"):
ctl.add_certificates(cert_stream)
elif file_name.endswith(".p12") or file_name.endswith(".pfx"):
# If a password is required, use add_archive(certStr, password).
ctl.add_archive(cert_stream)
except Exception as e:
print(f"Could not add certificate '{file_name}' to custom trust list: {e}")
else:
print(f"Directory {cert_dir} is missing. No certificates were added to the custom trust list.")
print()

profile.custom_trust_list = ctl

# Configure validation options
validation_options = profile.validation_options
validation_options.time_source = TimeSource.PROOF_OF_EXISTENCE | TimeSource.EXPIRED_TIME_STAMP | TimeSource.SIGNATURE_TIME
validation_options.certificate_sources = DataSource.EMBED_IN_SIGNATURE | DataSource.EMBED_IN_DOCUMENT | DataSource.CUSTOM_TRUST_LIST

# Disable revocation checks.
profile.signing_cert_trust_constraints.revocation_check_policy = RevocationCheckPolicy.NO_CHECK
profile.time_stamp_trust_constraints.revocation_check_policy = RevocationCheckPolicy.NO_CHECK

# Validate ALL signatures in the document (not only the latest)
signatureSelector = SignatureSelector.ALL

# Create the validator object and event listeners
validator = Validator()
validator.add_constraint_handler(on_constraint_event)

try:
with io.FileIO(input_file, 'rb') as in_stream:
# Open input document
# If a password is required, use Open(inStr, password)
with Document.open(in_stream) as document:
print("Validation Constraints")
results = validator.validate(document, profile, signatureSelector)
print()
print(f"Signatures validated: {len(results)}")
print()

for result in results:
field = result.signature_field
print(f"{field.field_name} of {field.name}")
try:
print(f" - Revision : {'latest' if field.revision.is_latest else 'intermediate'}")
except Exception as ex:
print(f"Unable to validate document Revision: {str(ex)}")

print_signature_content(result.signature_content, field.is_full_revision_covered)
print()
except Exception as e:
print(f"Unable to validate file: {e}")
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

validate(input_file, cert_dir)
Download code sample
Function Validate(inputFile As String, certDir As String) As Integer
' Use the default validation profile as a base for further settings
Dim profile = New PdfTools.SignatureValidation.Profiles.Default()

' For offline operation, build a custom trust list from the file system
' and disable external revocation checks
If Not String.IsNullOrEmpty(certDir) Then
Console.WriteLine("Using 'offline' validation mode with custom trust list.")
Console.WriteLine()

' create a CustomTrustList to hold the certificates
Dim ctl = New CustomTrustList()

' Iterate through files in the certificate directory and add certificates
' to the custom trust list
If Directory.Exists(certDir) Then
Dim directoryListing = Directory.EnumerateFiles(certDir)
For Each fileName In directoryListing
Try
Using certStr = File.OpenRead(fileName)
If fileName.EndsWith(".cer") OrElse fileName.EndsWith(".pem") Then
ctl.AddCertificates(certStr)
ElseIf fileName.EndsWith(".p12") OrElse fileName.EndsWith(".pfx") Then
' If a password is required, use addArchive(certStr, password).
ctl.AddArchive(certStr)
End If
End Using
Catch e As Exception
Console.WriteLine("Could not add certificate '" & fileName & "' to custom trust list: " & e.Message)
End Try
Next
Else
' Handle the case where dir is not a directory
Console.WriteLine("Directory " & certDir & " is missing. No certificates were added to the custom trust list.")
End If
Console.WriteLine()

' Assign the custom trust list to the validation profile
profile.CustomTrustList = ctl

' Allow validation from embedded file sources and the custom trust list
Dim vo = profile.ValidationOptions
vo.TimeSource = TimeSource.ProofOfExistence Or TimeSource.ExpiredTimeStamp Or TimeSource.SignatureTime
vo.CertificateSources = DataSource.EmbedInSignature Or DataSource.EmbedInDocument Or DataSource.CustomTrustList

' Disable revocation checks.
profile.SigningCertTrustConstraints.RevocationCheckPolicy = RevocationCheckPolicy.NoCheck
profile.TimeStampTrustConstraints.RevocationCheckPolicy = RevocationCheckPolicy.NoCheck
End If

' Validate ALL signatures in the document (not only the latest)
Dim signatureSelector = SignatureValidation.SignatureSelector.All

' Create the validator object and event listeners
Dim validator = New Validator()
AddHandler validator.Constraint, Sub(s, e)
Console.WriteLine(" - " & e.Signature.Name & If(e.DataPart.Length > 0, ": " & e.DataPart, "") & ": " &
ConstraintToString(e.Indication, e.SubIndication, e.Message))
End Sub

Try
Using inStr = File.OpenRead(inputFile)
' Open input document
' If a password is required, use Open(inStr, password)
Using document = Pdf.Document.Open(inStr)

' Run the validate method passing the document, profile and selector
Console.WriteLine("Validation Constraints")
Dim results = validator.Validate(document, profile, signatureSelector)

Console.WriteLine()
Console.WriteLine("Signatures validated: " & results.Count)
Console.WriteLine()

' Print results
For Each result In results
Dim field = result.SignatureField
Console.WriteLine(field.FieldName & " of " & field.Name)
Try
Console.WriteLine(" - Revision : " & If(field.Revision.IsLatest, "latest", "intermediate"))
Catch ex As Exception
Console.WriteLine("Unable to validate document Revision: " & ex.Message)
End Try

PrintContent(result.SignatureContent, field.IsFullRevisionCovered)
Console.WriteLine()
Next

Return 0
End Using
End Using
Catch ex As Exception
Console.WriteLine("Unable to validate file: " & ex.Message)
Return 5
End Try
End Function
' Helper functions to print signature validation details
Private Sub PrintContent(content As SignatureContent, isFullRevisionCovered As Boolean?)
If content IsNot Nothing Then
Console.WriteLine(" - Validity : " & ConstraintToString(content.Validity, isFullRevisionCovered))
If TypeOf content Is UnsupportedSignatureContent Then
' Do nothing
ElseIf TypeOf content Is CmsSignatureContent Then
Dim signature As CmsSignatureContent = CType(content, CmsSignatureContent)
Console.WriteLine(" - Validation: " & signature.ValidationTime.ToString() & " from " & signature.ValidationTimeSource.ToString())
Console.WriteLine(" - Hash : " & signature.HashAlgorithm.ToString())
Console.WriteLine(" - Signing Cert")
PrintContent(signature.SigningCertificate)
Console.WriteLine(" - Chain")
For Each cert In signature.CertificateChain
Console.WriteLine(" - Issuer Cert " & (signature.CertificateChain.IndexOf(cert) + 1))
PrintContent(cert)
Next
Console.WriteLine(" - Chain : " & If(signature.CertificateChain.IsComplete, "complete", "incomplete") & " chain")
Console.WriteLine(" Time-Stamp")
PrintContent(signature.TimeStamp, Nothing)
ElseIf TypeOf content Is TimeStampContent Then
Dim timeStamp As TimeStampContent = CType(content, TimeStampContent)
Console.WriteLine(" - Validation: " & timeStamp.ValidationTime.ToString() & " from " & timeStamp.ValidationTimeSource.ToString())
Console.WriteLine(" - Hash : " & timeStamp.HashAlgorithm.ToString())
Console.WriteLine(" - Time : " & timeStamp.Date.ToString())
Console.WriteLine(" - Signing Cert")
PrintContent(timeStamp.SigningCertificate)
Console.WriteLine(" - Chain")
For Each cert In timeStamp.CertificateChain
Console.WriteLine(" - Issuer Cert " & (timeStamp.CertificateChain.IndexOf(cert) + 1))
PrintContent(cert)
Next
Console.WriteLine(" - Chain : " & If(timeStamp.CertificateChain.IsComplete, "complete", "incomplete") & " chain")
Else
Console.WriteLine("Unsupported signature content type " & content.GetType().Name)
End If
Else
Console.WriteLine(" - null")
End If
End Sub
Private Sub PrintContent(cert As Certificate)
If cert IsNot Nothing Then
Console.WriteLine(" - Subject : " & cert.SubjectName)
Console.WriteLine(" - Issuer : " & cert.IssuerName)
Console.WriteLine(" - Validity : " & cert.NotBefore.ToString() & " - " & cert.NotAfter.ToString())
Try
Console.WriteLine(" - Fingerprint: " & FormatSha1Digest(New BigInteger(SHA1.Create().ComputeHash(cert.RawData)).ToByteArray(), "-"))
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.WriteLine(" - Source : " & cert.Source.ToString())
Console.WriteLine(" - Validity : " & ConstraintToString(cert.Validity))
Else
Console.WriteLine(" - null")
End If
End Sub
Private Function ConstraintToString(constraint As ConstraintResult) As String
Return ConstraintToString(constraint.Indication, constraint.SubIndication, constraint.Message)
End Function
Private Function ConstraintToString(constraint As ConstraintResult, isFullRevisionCovered As Boolean?) As String
Return ConstraintToString(constraint.Indication, constraint.SubIndication, constraint.Message, isFullRevisionCovered)
End Function
Private Function ConstraintToString(indication As Indication, subIndication As SubIndication, message As String) As String
Return If(indication = indication.Valid, "", If(indication = indication.Indeterminate, "?", "!")) & "" &
subIndication.ToString() & " " &
message
End Function
Private Function ConstraintToString(indication As Indication, subIndication As SubIndication, message As String, isFullRevisionCovered As Boolean?) As String
If isFullRevisionCovered Is Nothing OrElse isFullRevisionCovered.Value Then
Return If(indication = indication.Valid, "", If(indication = indication.Indeterminate, "?", "!")) & "" &
subIndication.ToString() & " " &
message
Else
Dim byteRangeInvalid = "!Invalid signature byte range."
If indication = indication.Valid Then
Return byteRangeInvalid
Else
Return byteRangeInvalid & " " & subIndication.ToString() & " " & message
End If
End If
End Function
' Helper function to generate a delimited SHA-1 digest string
Private Function FormatSha1Digest(bytes As Byte(), delimiter As String) As String
Dim result = New StringBuilder()
For Each aByte In bytes
Dim number = CInt(aByte) And &HFF
Dim hex = number.ToString("X2")
result.Append(hex.ToUpper() & delimiter)
Next
Return result.ToString().Substring(0, result.Length - delimiter.Length)
End Function

Add a document time-stamp to a PDF using the Swisscom Signing Service

Download code sample
// Configure the SSL client certificate to connect to the service
var httpClientHandler = new HttpClientHandler();
using (var sslClientCert = File.OpenRead(@"C:\path\to\clientcert.p12"))
httpClientHandler.SetClientCertificate(sslClientCert, "***insert password***");

// Connect to the Swisscom Signing Service
using var session = new SwisscomSigSrv.Session(new Uri("https://ais.swisscom.com"), httpClientHandler);

// Add a document time-stamp to a PDF
AddTimestamp(session, identity, inPath, outPath);
static void AddTimestamp(SwisscomSigSrv.Session session, string identity, string inPath, string outPath)
{
// Create time-stamp configuration
var timestamp = session.CreateTimestamp(identity);

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Add the document time-stamp
using var outDoc = new Signer().AddTimestamp(inDoc, timestamp, outStr);
}
Download code sample
// Configure the SSL client certificate to connect to the service
HttpClientHandler httpClientHandler = new HttpClientHandler();
try (FileStream sslClientCert = new FileStream("C:/path/to/clientcert.p12", FileStream.Mode.READ_ONLY))
{
httpClientHandler.setClientCertificate(sslClientCert, "***insert password***");
}

// Connect to the Swisscom Signing Service
try (Session session = new Session(new URI("https://ais.swisscom.com"), httpClientHandler))
{
// Add a document time-stamp to a PDF
addTimestamp(session, identity, inPath, outPath);
}
private static void addTimestamp(Session session, String identity, String inPath, String outPath) throws Exception
{
// Create time-stamp configuration
TimestampConfiguration timestamp = session.createTimestamp(identity);

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Add the document time-stamp
Document outDoc = new Signer().addTimestamp(inDoc, timestamp, outStr))
{
}
}
Download code sample
def add_timestamp(session: Session, identity: str, input_path: str, output_path: str):
# Create timestamp configuration
timestamp = session.create_timestamp(identity)

# Open input document
with io.FileIO(input_path, 'rb') as input_stream:
with Document.open(input_stream) as input_document:
# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Add the document timestamp
signer = Signer()
signer.add_timestamp(input_document, timestamp, output_stream)
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

# Configure the SSL client certificate to connect to the service
http_client_handler = HttpClientHandler()
with io.FileIO("C:/path/to/clientcert.p12", 'rb') as cert_stream:
http_client_handler.set_client_certificate(cert_stream, "***insert password***")

# Connect to the Swisscom Signing Service
with Session("https://ais.swisscom.com", http_client_handler) as session:
# Add a document timestamp to a PDF
add_timestamp(session, identity, input_path, output_path)
Download code sample
' Configure the SSL client certificate to connect to the service
Dim httpClientHandler = New HttpClientHandler()
Using sslClientCert = File.OpenRead("C:\path\to\clientcert.p12")
httpClientHandler.SetClientCertificate(sslClientCert, "***insert password***")
End Using

' Connect to the Swisscom Signing Service
Using session = New SwisscomSigSrv.Session(New Uri("https://ais.swisscom.com"), httpClientHandler)

' Add a document time-stamp to a PDF
AddTimestamp(session, identity, inPath, outPath)
End Using
Sub AddTimestamp(session As SwisscomSigSrv.Session, identity As String, inPath As String, outPath As String)
' Create time-stamp configuration
Dim timestamp = session.CreateTimestamp(identity)

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Add the document time-stamp
Using outDoc = New Signer().AddTimestamp(inDoc, timestamp, outStr)
End Using
End Using
End Using
End Using
End Sub

Sign a PDF using the Swisscom Signing Service

Download code sample
// Configure the SSL client certificate to connect to the service
var httpClientHandler = new HttpClientHandler();
using (var sslClientCert = File.OpenRead(@"C:\path\to\clientcert.p12"))
httpClientHandler.SetClientCertificate(sslClientCert, "***insert password***");

// Connect to the Swisscom Signing Service
using var session = new SwisscomSigSrv.Session(new Uri("https://ais.swisscom.com"), httpClientHandler);

// Sign a PDF document
Sign(session, identity, commonName, inPath, outPath);
static void Sign(SwisscomSigSrv.Session session, string identity, string commonName, string inPath, string outPath)
{
// Create a signing certificate for a static identity
var signature = session.CreateSignatureForStaticIdentity(identity, commonName);

// Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.EmbedValidationInformation = true;

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Sign the document
using var outDoc = new Signer().Sign(inDoc, signature, outStr);
}
Download code sample
// Configure the SSL client certificate to connect to the service
HttpClientHandler httpClientHandler = new HttpClientHandler();
try (FileStream sslClientCert = new FileStream("C:/path/to/clientcert.p12", FileStream.Mode.READ_ONLY))
{
httpClientHandler.setClientCertificate(sslClientCert, "***insert password***");
}

// Connect to the Swisscom Signing Service
try (Session session = new Session(new URI("https://ais.swisscom.com"), httpClientHandler))
{
// Sign a PDF document
sign(session, identity, commonName, inPath, outPath);
}
private static void sign(Session session, String identity, String commonName, String inPath, String outPath) throws Exception
{
// Create a signing certificate for a static identity
// This can be re-used to sign multiple documents
SignatureConfiguration signature = session.createSignatureForStaticIdentity(identity, commonName);

// Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.setEmbedValidationInformation(true);

try (
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create output stream
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Sign the input document
Document outDoc = new Signer().sign(inDoc, signature, outStr))
{
}
}
Download code sample
def sign(session: Session, identity: str, common_name: str, input_path: str, output_path: str):
# Create a signing certificate for a static identity
signature = session.create_signature_for_static_identity(identity, common_name)

# Embed validation information to enable the long-term validation (LTV) of the signature (default)
signature.embed_validation_information = True

# Open input document
with io.FileIO(input_path, 'rb') as input_stream:
with Document.open(input_stream) as input_document:
# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Sign the document
signer = Signer()
signer.sign(input_document, signature, output_stream)
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

# Configure the SSL client certificate to connect to the service
http_client_handler = HttpClientHandler()
with io.FileIO("C:/path/to/clientcert.p12", 'rb') as cert_stream:
http_client_handler.set_client_certificate(cert_stream, "***insert password***")

# Connect to the Swisscom Signing Service
with Session("https://ais.swisscom.com", http_client_handler) as session:
# Sign the PDF document
sign(session, identity, common_name, input_path, output_path)
Download code sample
' Configure the SSL client certificate to connect to the service
Dim httpClientHandler = New HttpClientHandler()
Using sslClientCert = File.OpenRead("C:\path\to\clientcert.p12")
httpClientHandler.SetClientCertificate(sslClientCert, "***insert password***")
End Using

' Connect to the Swisscom Signing Service
Using session = New SwisscomSigSrv.Session(New Uri("https://ais.swisscom.com"), httpClientHandler)

' Sign a PDF document
Sign(session, identity, commonName, inPath, outPath)
End Using
Sub Sign(session As SwisscomSigSrv.Session, identity As String, commonName As String, inPath As String, outPath As String)
' Create a signing certificate for a static identity
Dim signature = session.CreateSignatureForStaticIdentity(identity, commonName)

' Embed validation information to enable the long term validation (LTV) of the signature (default)
signature.EmbedValidationInformation = True

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Sign the document
Using outDoc = New Signer().Sign(inDoc, signature, outStr)
End Using
End Using
End Using
End Using
End Sub

Sign a PDF and add a visual appearance

Download code sample
static void Sign(string certificateFile, string password, string appConfigFile, string inPath, string outPath)
{
// Create a session to the built-in cryptographic provider
using var session = new BuiltIn.Provider();

// Open certificate file
using var pfxStr = File.OpenRead(certificateFile);

// Create signature configuration from PFX (or P12) file
BuiltIn.SignatureConfiguration signature = session.CreateSignatureFromCertificate(pfxStr, password);

// Create appearance from either an XML or a json file
using var appStream = File.OpenRead(appConfigFile);
if (Path.GetExtension(appConfigFile) == ".xml")
signature.Appearance = Appearance.CreateFromXml(appStream);
else
signature.Appearance = Appearance.CreateFromJson(appStream);

signature.Appearance.PageNumber = 1;
signature.Appearance.CustomTextVariables.Add("company", "Daily Planet");

// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create stream for output file
using var outStr = File.Create(outPath);

// Sign the input document
using var outDoc = new Signer().Sign(inDoc, signature, outStr);
}
Download code sample
private static void sign(String certificateFile, String password, String appConfigFile, String inPath, String outPath) throws Exception
{
try (
// Create a session to the built-in cryptographic provider
Provider session = new Provider();

// Open certificate file
FileStream pfxStr = new FileStream(certificateFile, FileStream.Mode.READ_ONLY))
{
// Create signature configuration from PFX (or P12) file
SignatureConfiguration signature = session.createSignatureFromCertificate(pfxStr, password);

try (
// Create appearance from either an XML or a json file
FileStream appConfigStr = new FileStream(appConfigFile, FileStream.Mode.READ_ONLY))
{
if (appConfigFile.toLowerCase().endsWith(".xml"))
signature.setAppearance(Appearance.createFromXml(appConfigStr));
else
signature.setAppearance(Appearance.createFromJson(appConfigStr));

signature.getAppearance().setPageNumber(1);
signature.getAppearance().getCustomTextVariables().put("company", "Daily Planet");

try(
// Open input document
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr);

// Create a stream for the output file
FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);

// Sign the input document
Document outDoc = new Signer().sign(inDoc, signature, outStr))
{
}
}
}
}
Download code sample
def sign(certificate_file: str, password: str, appearance_config_file: str, input_path: str, output_path: str):
# Create a session with the built-in cryptographic provider
with Provider() as session:
# Open certificate file
with io.FileIO(certificate_file, 'rb') as pfx_stream:
# Create signature configuration from PFX (or P12) file
signature = session.create_signature_from_certificate(pfx_stream, password)

# Create appearance from either an XML or JSON file
with io.FileIO(appearance_config_file, 'rb') as appearance_stream:
if appearance_config_file.endswith(".xml"):
signature.appearance = Appearance.create_from_xml(appearance_stream)
else:
signature.appearance = Appearance.create_from_json(appearance_stream)

signature.appearance.page_number = 1
signature.appearance.custom_text_variables["company"] = "Daily Planet"

# Open input document
with io.FileIO(input_path, 'rb') as input_stream:
with Document.open(input_stream) as input_document:
# Create stream for output file
with io.FileIO(output_path, 'wb+') as output_stream:
# Sign the input document
signer = Signer()
signer.sign(input_document, signature, output_stream)
# Optional: Set your proxy configuration
# Sdk.set_proxy("http://myproxy:8080")

# Sign a PDF document
sign(certificate_file, password, appearance_config_file, input_path, output_path)
Download code sample
Sub Sign(certificateFile As String, password As String, appConfigFile As String, inPath As String, outPath As String)
' Create a session to the built-in cryptographic provider
Using session As New BuiltIn.Provider()

' Open certificate file
Using pfxStr = File.OpenRead(certificateFile)

' Create signature configuration from PFX (or P12) file
Dim signature As BuiltIn.SignatureConfiguration = session.CreateSignatureFromCertificate(pfxStr, password)

' Create appearance from either an XML or a JSON file
Using appStream = File.OpenRead(appConfigFile)
If Path.GetExtension(appConfigFile) = ".xml" Then
signature.Appearance = Appearance.CreateFromXml(appStream)
Else
signature.Appearance = Appearance.CreateFromJson(appStream)
End If
End Using

signature.Appearance.PageNumber = 1
signature.Appearance.CustomTextVariables.Add("company", "Daily Planet")

' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create stream for output file
Using outStr = File.Create(outPath)

' Sign the input document
Using outDoc = New Signer().Sign(inDoc, signature, outStr)
End Using
End Using
End Using
End Using
End Using
End Using
End Sub

Text extraction

Chat with a PDF

Download code sample
def extract_text(input_file_path: str) -> str:
# Open input document
with open(input_file_path, 'rb') as in_stream:
with Document.open(in_stream) as in_doc:
# Set extraction options
options = TextOptions()
options.extraction_format = TextExtractionFormat.DOCUMENT_ORDER

# Extract text from PDF
extractor = Extractor()
with io.BytesIO() as output_stream:
extractor.extract_text(in_doc, output_stream, options)
return output_stream.getvalue().decode('utf-8')
def answer_question(text: str, question: str) -> str:
client = OpenAI(api_key="***insert-open-ai-api-key***")

prompt = (
"You are a helpful assistant. Use the provided text to answer the "
"question. If the answer is not in the text, say 'Not found'.\n\n"
f"Text: {text}\nQuestion: {question}\nAnswer:"
)

response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You answer questions based on text."},
{"role": "user", "content": prompt}
],
)

return response.choices[0].message.content.strip()
extracted_text = extract_text(input_path)
answer = answer_question(extracted_text, question)
print(f"Question: {question}")
print(f"Answer: {answer}")

Extract text mimicking layout

Download code sample
private static void ExtractText(string inPath, string outDir)
{
// Open input document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create directory if not exists
if (!Directory.Exists(outDir))
{
Directory.CreateDirectory(outDir);
}

var options = new TextOptions();
options.ExtractionFormat = TextExtractionFormat.Monospace;
options.AdvanceWidth = Length.Parse("9.2pt");

// Extract text page per page from the document
Extractor extractor = new Extractor();
for (int i = 0; i < inDoc.PageCount; i++)
{
using var outStr = File.Create(Path.Combine(outDir, $"page{i + 1}.txt"));
extractor.ExtractText(inDoc, outStr, options, i + 1, i + 1);
}
}
Download code sample
private static void extractText(String inPath, String outDir) throws Exception {
// Open input document
try (
FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr)
) {
// Create directory if it does not exist
File dir = new File(outDir);
if (!dir.exists()) {
dir.mkdirs();
}

// Set text extraction options
TextOptions options = new TextOptions();
options.setExtractionFormat(TextExtractionFormat.MONOSPACE);
options.setAdvanceWidth(Length.parse("9.2pt"));

// Extract text page by page from the document
Extractor extractor = new Extractor();
for (int i = 0; i < inDoc.getPageCount(); i++) {
try (
FileStream outStr = new FileStream(outDir + File.separator + "page" + (i + 1) + ".txt", FileStream.Mode.READ_WRITE_NEW)
) {
extractor.extractText(inDoc, outStr, options, i + 1, i + 1);
}
}
}
}
Download code sample
def extract_text(input_file_path: str, output_directory: str):
# Open input document
with open(input_file_path, 'rb') as in_stream:
with Document.open(in_stream) as in_doc:
# Create directory if it doesn't exist
if not os.path.exists(output_directory):
os.makedirs(output_directory)

# Set extraction options
options = TextOptions()
options.extraction_format = TextExtractionFormat.MONOSPACE
options.advance_width = 9.2

# Extract text page by page
extractor = Extractor()
for i in range(in_doc.page_count):
output_file = os.path.join(output_directory, f"page{i + 1}.txt")
with open(output_file, 'wb') as out_stream:
extractor.extract_text(in_doc, out_stream, options, i + 1, i + 1)
extract_text(input_path, output_dir)
Download code sample
Sub ExtractText(inPath As String, outDir As String)
' Open input document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)
' Create directory if not exists
If Not Directory.Exists(outDir) Then
Directory.CreateDirectory(outDir)
End If

Dim options As New TextOptions()
options.ExtractionFormat = TextExtractionFormat.Monospace
options.AdvanceWidth = Length.Parse("9.2pt")

' Extract text page per page from the document
Dim extractor As New Extractor()
For i As Integer = 0 To inDoc.PageCount - 1
Using outStr = File.Create(Path.Combine(outDir, $"page{i + 1}.txt"))
extractor.ExtractText(inDoc, outStr, options, i + 1, i + 1)
End Using
Next
End Using
End Using
End Sub

Validate the conformance of documents

Validate PDF conformance

Download code sample
void ErrorListener(void* pContext, const TCHAR* szDataPart, const TCHAR* szMessage,
TPdfToolsPdfAValidation_ErrorCategory iCategory, const TCHAR* szContext, int iPageNo, int iObjectNo)
{
if (iPageNo > 0)
_tprintf(_T("- %d: %s (%s on page %d)\n"), iCategory, szMessage, szContext, iPageNo);
else
_tprintf(_T("- %d: %s (%s)\n"), iCategory, szMessage, szContext);
}
void Validate(const TCHAR* szInPath)
{
TPdfToolsPdf_Document* pInDoc = NULL;
TPdfToolsPdfAValidation_Validator* pValidator = NULL;
TPdfToolsPdfAValidation_ValidationResult* pResult = NULL;

// Open input document
FILE* pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
TPdfToolsSys_StreamDescriptor inDesc;
PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Failed to open document \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
szErrBuf, PdfTools_GetLastError());

// Create a validator object that writes all validation error messages to the console
pValidator = PdfToolsPdfAValidation_Validator_New();
PdfToolsPdfAValidation_Validator_AddErrorHandler(pValidator, NULL,
(TPdfToolsPdfAValidation_Validator_Error)ErrorListener);

// Validate the standard conformance of the document
pResult = PdfToolsPdfAValidation_Validator_Validate(pValidator, pInDoc, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pResult, _T("Failed to validate document. %s (ErrorCode: 0x%08x).\n"), szErrBuf,
PdfTools_GetLastError());

// Report validation result
TPdfToolsPdf_Conformance iClaimedConformance;
PdfToolsPdf_Document_GetConformance(pInDoc, &iClaimedConformance);
if (PdfToolsPdfAValidation_ValidationResult_IsConforming(pResult))
printf("Document conforms to %s.\n", PdfToolsPdf_Conformance_ToStringA(iClaimedConformance));
else
printf("Document does not conform to %s.\n", PdfToolsPdf_Conformance_ToStringA(iClaimedConformance));

cleanup:
PdfTools_Release(pResult);
PdfTools_Release(pValidator);
PdfToolsPdf_Document_Close(pInDoc);
if (pInStream)
fclose(pInStream);
}
Download code sample
private static ValidationResult Validate(string inPath)
{
// Open the document
using var inStr = File.OpenRead(inPath);
using var inDoc = Document.Open(inStr);

// Create a validator object that writes all validation error messages to the console
var validator = new Validator();
validator.Error += (s, e) => Console.WriteLine("- {0}: {1} ({2}{3})", e.Category, e.Message, e.Context, e.PageNo > 0 ? " on page" + e.PageNo : "");

// Validate the standard conformance of the document
return validator.Validate(inDoc);
}
Download code sample
private static ValidationResult validate(String inPath) throws Exception
{
// Open input document
try (FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
Document inDoc = Document.open(inStr))
{
// Create a validator object that writes all validation error messages to the console
Validator validator = new Validator();
validator.addErrorListener(
(Validator.Error error) ->
System.out.format("- %s: %s (%s%s)%n", error.getCategory(), error.getMessage(), error.getContext(), error.getPageNo() > 0 ? String.format(" on page %d", error.getPageNo()) : "")
);

// Validate the standard conformance of the document
return validator.validate(inDoc);
}
}
Download code sample
def error_listener(context, data_part: str, message: str, category: ErrorCategory, context_text: str, page_no: int, object_no: int):
if page_no > 0:
print(f"- {category.name}: {message.decode()} ({context_text.decode()} on page {page_no})")
else:
print(f"- {category.name}: {message.decode()} ({context_text.decode()})")
def validate(input_file_path: str):
# Open the document
with io.FileIO(input_file_path, 'rb') as in_stream:
with Document.open(in_stream) as input_document:
# Create a validator object that writes all validation error messages to the console
validator = Validator()
validator.add_error_handler(error_listener)

# Validate the standard conformance of the document
return validator.validate(input_document)
validation_result = validate(input_file_path)

# Report the validation result
if validation_result.is_conforming:
print(f"Document conforms to {Conformance(validation_result.conformance).name}.")
else:
print(f"Document does not conform to {Conformance(validation_result.conformance).name}.")
Download code sample
Private Function Validate(inPath As String) As ValidationResult
' Open the document
Using inStr = File.OpenRead(inPath)
Using inDoc = Document.Open(inStr)

' Create a validator object that writes all validation error messages to the console
Dim validator = New Validator()
AddHandler validator.Error, Sub(s, e)
Console.WriteLine("- {0}: {1} ({2}{3})", e.Category, e.Message, e.Context, If(e.PageNo > 0, " on page" & e.PageNo, ""))
End Sub

' Validate the standard conformance of the document
Return validator.Validate(inDoc)
End Using
End Using
End Function