What's new
What’s new in Aspose.PDF 25.5
The ’extract_certificate’ method extracts digital certificates from signatures embedded in a PDF document.
import aspose.pdf as ap
def extract_certificate(self, infile):
path_infile = self.data_dir + infile
# Open PDF document
with ap.Document(path_infile) as document:
with ap.facades.PdfFileSignature(document) as signature:
# Get signature names
signature_names = signature.get_signature_names(True)
for signature_name in signature_names:
# Extract certificate
certificate = []
if signature.try_extract_certificate(signature_name, certificate):
print(certificate[0] is not None)
The ‘create_ordered_list’ method generates a tagged PDF document with a structured numbered list, including nested sublists.
import aspose.pdf as ap
def create_ordered_list(self, outfile):
path_outfile = self.data_dir + outfile
# Create or open PDF document
with ap.Document() as document:
content = document.tagged_content
root_element = content.root_element
content.set_language("en-US")
root_list = content.create_list_element()
span_for_lbl_1 = content.create_span_element()
span_for_lbl_1.set_text("1. ")
position_settings = ap.tagged.PositionSettings()
position_settings.is_in_line_paragraph = True
span_for_lbl_1.adjust_position(position_settings)
span_for_body_1 = content.create_span_element()
span_for_body_1.set_text("bread")
span_for_body_1.adjust_position(position_settings)
lbl_1 = content.create_list_lbl_element()
lbl_1.append_child(span_for_body_1, True)
l_body_1 = content.create_list_l_body_element()
l_body_1.append_child(span_for_lbl_1, True)
li_1 = content.create_list_li_element()
li_1.append_child(lbl_1, True)
li_1.append_child(l_body_1, True)
root_list.append_child(li_1, True)
span_for_lbl_2 = content.create_span_element()
span_for_lbl_2.set_text("2. ")
span_for_body_2 = content.create_span_element()
span_for_body_2.set_text("milk")
span_for_body_2.adjust_position(position_settings)
lbl_2 = content.create_list_lbl_element()
lbl_2.append_child(span_for_lbl_2, True)
l_body_2 = content.create_list_l_body_element()
l_body_2.append_child(span_for_body_2, True)
li_2 = content.create_list_li_element()
li_2.append_child(lbl_2, True)
li_2.append_child(l_body_2, True)
root_list.append_child(li_2, True)
nested_list_depth_1 = content.create_list_element()
span_for_lbl_3_1 = content.create_span_element()
span_for_lbl_3_1.set_text("3.1. ")
position_settings_lbl_3_1 = ap.tagged.PositionSettings()
position_settings_lbl_3_1.is_in_line_paragraph = False
margin_info = ap.MarginInfo()
margin_info.left = 50
position_settings_lbl_3_1.margin = margin_info
span_for_lbl_3_1.adjust_position(position_settings_lbl_3_1)
span_for_body_3_1 = content.create_span_element()
span_for_body_3_1.set_text("apples")
span_for_body_3_1.adjust_position(position_settings)
lbl_3_1 = content.create_list_lbl_element()
lbl_3_1.append_child(span_for_lbl_3_1, True)
l_body_3_1 = content.create_list_l_body_element()
l_body_3_1.append_child(span_for_body_3_1, True)
li_3_1 = content.create_list_li_element()
li_3_1.append_child(lbl_3_1, True)
li_3_1.append_child(l_body_3_1, True)
nested_list_depth_1.append_child(li_3_1, True)
span_for_lbl_3_2 = content.create_span_element()
span_for_lbl_3_2.set_text("3.2. ")
span_for_lbl_3_2.adjust_position(position_settings_lbl_3_1)
span_for_body_3_2 = content.create_span_element()
span_for_body_3_2.set_text("banana")
span_for_body_3_2.adjust_position(position_settings)
lbl_3_2 = content.create_list_lbl_element()
lbl_3_2.append_child(span_for_lbl_3_2, True)
l_body_3_2 = content.create_list_l_body_element()
l_body_3_2.append_child(span_for_body_3_2, True)
li_3_2 = content.create_list_li_element()
li_3_2.append_child(lbl_3_2, True)
li_3_2.append_child(l_body_3_2, True)
nested_list_depth_1.append_child(li_3_2, True)
span_for_lbl_3 = content.create_span_element()
span_for_lbl_3.set_text("3. ")
span_for_body_3 = content.create_span_element()
span_for_body_3.set_text("fruits")
span_for_body_3.adjust_position(position_settings)
lbl_3 = content.create_list_lbl_element()
lbl_3.append_child(span_for_lbl_3, True)
l_body_3 = content.create_list_l_body_element()
l_body_3.append_child(span_for_body_3, True)
li_3 = content.create_list_li_element()
li_3.append_child(lbl_3, True)
li_3.append_child(l_body_3, True)
l_body_3.append_child(nested_list_depth_1, True)
root_list.append_child(li_3, True)
root_element.append_child(root_list, True)
# Save Tagged PDF Document
document.save(path_outfile)
This example verifies a digital signature in a PDF document using a public key certificate.
import aspose.pdf as ap
def verify_with_public_key_certificate1(self, certificate, infile):
path_infile = self.data_dir + infile
# Create an instance of PdfFileSignature for working with signatures in the document
with ap.facades.PdfFileSignature(path_infile) as file_sign:
# Get a list of signatures
signature_names = file_sign.get_signature_names(True)
# Verify the signature with the given name.
return file_sign.verify_signature(signature_names[0], certificate)
Next feature converts a dynamic XFA (XML Forms Architecture) PDF form into a standard AcroForm PDF.
import aspose.pdf as ap
def convert_xfa_form_with_ignore_needs_rendering(self, infile, outfile):
path_infile = self.data_dir + infile
path_outfile = self.data_dir + outfile
# Load dynamic XFA form
with ap.Document(path_infile) as document:
# check if XFA is present & if rendering should be overwritten
if not document.form.needs_rendering and document.form.has_xfa:
document.form.ignore_needs_rendering = True
# Set the form fields type as standard AcroForm
document.form.type = ap.forms.FormType.STANDARD
# Save the resultant PDF
document.save(path_outfile)
This code snippet converts a PDF document to XPS format while replacing missing or unavailable fonts with a specified default font.
import aspose.pdf as ap
def replace_font_when_converting_pdf_to_xps(self, infile, outfile):
path_infile = self.data_dir + infile
path_outfile = self.data_dir + outfile
# Create XpsSaveOptions instance
xps_save_options = ap.XpsSaveOptions()
# use_embedded_true_type_fonts option specifies whether to use embedded TrueType fonts
xps_save_options.use_embedded_true_type_fonts = False
# The specified default font will be used if the embedded font name cannot be found in the system
xps_save_options.default_font = "Courier New"
# Open PDF document
doc = ap.Document(path_infile)
# Save the resultant XPS
doc.save(path_outfile, xps_save_options)
What’s new in Aspose.PDF 25.4
This version converts an existing PDF document into PDF/A-1b format.
import aspose.pdf as ap
def convert_to_pdfa_with_automatic_tagging(self, infile, outfile, outlogfile):
path_infile = self.data_dir + infile
path_outfile = self.data_dir + outfile
path_outlogfile = self.data_dir + outlogfile
# Open PDF document
with ap.Document(path_infile) as document:
# Create conversion options
options = ap.PdfFormatConversionOptions(path_outlogfile, ap.PdfFormat.PDF_A_1B, ap.ConvertErrorAction.DELETE)
# Create auto-tagging settings
# aspose.pdf.AutoTaggingSettings.default may be used to set the same settings as given below
auto_tagging_settings = ap.AutoTaggingSettings()
# Enable auto-tagging during the conversion process
auto_tagging_settings.enable_auto_tagging = True
# Use the heading recognition strategy that's optimal for the given document structure
auto_tagging_settings.heading_recognition_strategy = ap.HeadingRecognitionStrategy.AUTO
# Assign auto-tagging settings to be used during the conversion process
options.auto_tagging_settings = auto_tagging_settings
# During the conversion, the document logical structure will be automatically created
document.convert(options)
# Save PDF document
document.save(path_outfile)
What’s new in Aspose.PDF 25.3
From 25.3 Aspose.PDF for Python via .NET library supports verifying whether the digital signatures in a PDF document have been compromised.
import aspose.pdf as ap
def check(self, infile):
path_infile = self.data_dir + infile
# Open PDF document
with ap.Document(path_infile) as document:
# Create the compromise detector instance
detector = ap.SignaturesCompromiseDetector(document)
results = []
# Check for compromise
if detector.check(results):
print("No signature compromise detected")
return
# Get information about compromised signatures
result = results[0]
if result.has_compromised_signatures:
print(f"Count of compromised signatures: {result.COMPROMISED_SIGNATURES.length}")
for signature_name in result.COMPROMISED_SIGNATURES:
print(f"Signature name: {signature_name.FULL_NAME}")
# Get info about signatures coverage
print(result.signatures_coverage)
Also supports adjusting the Table position in PDF.
import aspose.pdf as ap
def adjust_table_position(self, outfile, outlogfile):
path_outfile = self.data_dir + outfile
path_outlogfile = self.data_dir + outlogfile
# Create PDF document
with ap.Document() as document:
# Create tagged content
tagged_content = document.tagged_content
tagged_content.set_title("Example table cell style")
tagged_content.set_language("en-US")
# Get root structure element
root_element = tagged_content.root_element
# Create table structure element
table_element = tagged_content.create_table_element()
root_element.append_child(table_element, True)
# Create position settings
position_settings = ap.tagged.PositionSettings()
position_settings.horizontal_alignment = ap.HorizontalAlignment.NONE
margin_info = ap.MarginInfo()
margin_info.left = 20
margin_info.right = 0
margin_info.top = 0
margin_info.bottom = 0
position_settings.margin = margin_info
position_settings.vertical_alignment = ap.VerticalAlignment.NONE
position_settings.is_first_paragraph_in_column = False
position_settings.is_kept_with_next = False
position_settings.is_in_new_page = False
position_settings.is_in_line_paragraph = False
# Adjust table position
table_element.adjust_position(position_settings)
table_t_head_element = table_element.create_t_head()
table_t_body_element = table_element.create_t_body()
table_t_foot_element = table_element.create_t_foot()
row_count = 4
col_count = 4
head_tr_element = table_t_head_element.create_tr()
head_tr_element.alternative_text = "Head Row"
for col_index in range(col_count):
th_element = head_tr_element.create_th()
th_element.set_text(f"Head {col_index}")
th_element.background_color = ap.Color.green_yellow
th_element.border = ap.BorderInfo(ap.BorderSide.ALL, 4.0, ap.Color.gray)
th_element.is_no_border = True
th_element.margin = ap.MarginInfo(16.0, 2.0, 8.0, 2.0)
th_element.alignment = ap.HorizontalAlignment.RIGHT
for row_index in range(row_count):
tr_element = table_t_body_element.create_tr()
tr_element.alternative_text = f"Row {row_index}"
for col_index in range(col_count):
col_span = 1
row_span = 1
if col_index == 1 and row_index == 1:
col_span = 2
row_span = 2
elif col_index == 2 and (row_index == 1 or row_index == 2):
continue
elif row_index == 2 and (col_index == 1 or col_index == 2):
continue
td_element = tr_element.create_td()
td_element.set_text(f"Cell [{row_index}, {col_index}]")
td_element.background_color = ap.Color.yellow
td_element.border = ap.BorderInfo(ap.BorderSide.ALL, 4.0, ap.Color.gray)
td_element.is_no_border = False
td_element.margin = ap.MarginInfo(8.0, 2.0, 8.0, 2.0)
td_element.alignment = ap.HorizontalAlignment.CENTER
cell_text_state = ap.text.TextState()
cell_text_state.foreground_color = ap.Color.dark_blue
cell_text_state.font_size = 7.5
cell_text_state.font_style = ap.text.FontStyles.BOLD
cell_text_state.font = ap.text.FontRepository.find_font("Arial")
td_element.default_cell_text_state = cell_text_state
td_element.is_word_wrapped = True
td_element.vertical_alignment = ap.VerticalAlignment.CENTER
td_element.col_span = col_span
td_element.row_span = row_span
foot_tr_element = table_t_foot_element.create_tr()
foot_tr_element.alternative_text = "Foot Row"
for col_index in range(col_count):
td_element = foot_tr_element.create_td()
td_element.set_text(f"Foot {col_index}")
# Save Tagged PDF Document
document.save(path_outfile)
# Check PDF/UA compliance
with ap.Document(path_outfile) as document:
# Create tagged content
is_pdf_ua_compliance = document.validate(path_outlogfile, ap.PdfFormat.PDF_UA_1)
print(f"PDF/UA compliance: {is_pdf_ua_compliance}")
What’s new in Aspose.PDF 25.2
From 25.2 Aspose.PDF for Python via .NET library supports PDF to PDF/X conversion.
import aspose.pdf as ap
def convert_pdf_to_pdf_x(self, infile, infile_icc, outfile):
path_infile = self.data_dir + infile
path_infile_icc = self.data_dir + infile_icc
path_outfile = self.data_dir + outfile
# Open PDF document
with ap.Document(path_infile) as document:
# Set up the desired PDF/X format with PdfFormatConversionOptions
options = ap.PdfFormatConversionOptions(ap.PdfFormat.PDF_X_4, ap.ConvertErrorAction.DELETE)
# Provide the name of the external ICC profile file (optional)
options.icc_profile_file_name = path_infile_icc
# Provide an output condition identifier and other necessary OutputIntent properties (optional)
options.output_intent = ap.OutputIntent("FOGRA39")
# Convert to PDF/X compliant document
document.convert(options)
# Save PDF document
document.save(path_outfile)
How to get information about Digital Signatures of PDF?
import aspose.pdf as ap
def verify(self, infile):
path_infile = self.data_dir + infile
# Open the document
with ap.Document(path_infile) as document:
# Create an instance of PdfFileSignature for working with signatures in the document
with ap.facades.PdfFileSignature(document) as signature:
# Get a list of signature names in the document
signature_names = signature.get_signature_names(True)
# Loop through all signature names to verify each one
for signature_name in signature_names:
# Verify that the signature with the given name is valid
if signature.verify_signature(signature_name) is False:
raise Exception('Not verified')
With this version it is now possible to create a TextBoxField with multiple widget annotations.
import aspose.pdf as ap
def add_text_box_field_to_pdf(self, outfile):
path_outfile = self.data_dir + outfile
# Create PDF document
with ap.Document() as document:
# Add a new page in the created document
page = document.pages.add()
# Defining an array with rectangle data for widget annotations.
# The number of elements in the array determines the number of widget annotations to add.
rects = [ap.Rectangle(10, 600, 110, 620, True), ap.Rectangle(10, 630, 110, 650, True),
ap.Rectangle(10, 660, 110, 680, True)]
# Defining an array with DefaultAppearance used to specify how widget annotations are displayed in the added field.
default_appearances = [ap.annotations.DefaultAppearance("Arial", 10, drawing.Color.dark_blue),
ap.annotations.DefaultAppearance("Helvetica", 12, drawing.Color.dark_green),
ap.annotations.DefaultAppearance(ap.text.FontRepository.find_font("TimesNewRoman"),
14, drawing.Color.dark_magenta)]
# Create a field
text_box_field = ap.forms.TextBoxField(page, rects)
# Setting the appearances of widget annotations
i = 0
for wa in text_box_field:
wa.default_appearance = default_appearances[i]
i += 1
text_box_field.value = "Text"
# Add field to the document
document.form.add(text_box_field)
# Save PDF document
document.save(path_outfile)
What’s new in Aspose.PDF 25.1
An option to save PDF to HTML by skipping all raster images.
import aspose.pdf as ap
def save_pdf_to_html_without_images(input_pdf_path: str, output_html_path: str):
doc = ap.Document(input_pdf_path)
html_save_options = ap.HtmlSaveOptions()
html_save_options.explicit_list_of_saved_pages = [1]
html_save_options.fixed_layout = True
html_save_options.font_saving_mode = ap.HtmlSaveOptions.FontSavingModes.ALWAYS_SAVE_AS_WOFF
html_save_options.parts_embedding_mode = ap.HtmlSaveOptions.PartsEmbeddingModes.EMBED_ALL_INTO_HTML
html_save_options.raster_images_saving_mode = ap.HtmlSaveOptions.RasterImagesSavingModes.DONT_SAVE
doc.save(output_html_path, html_save_options)
Possibility to validate a PDF signature using a Certificate Authority (CA) Server:
import aspose.pdf as ap
def verify_signature_with_options(input_pdf_path: str):
document = ap.Document(input_pdf_path)
pdf_sign = ap.facades.PdfFileSignature(document)
for sign_name in pdf_sign.get_sign_names(True):
options = ap.security.ValidationOptions()
options.validation_mode = ap.security.ValidationMode.STRICT
options.validation_method = ap.security.ValidationMethod.AUTO
options.request_timeout = 20000
validation_results = []
verified = pdf_sign.verify_signature(sign_name, options, validation_results)
print(validation_results[0].status)
print(validation_results[0].message)
Cross-platform PDF signature validation using SHA-3 hashing algorithms:
import aspose.pdf as ap
import aspose.pydrawing as drawing
def sign_with_sha3(input_pdf_path: str, cert: str, password: str, output_pdf_path: str):
document = ap.Document(input_pdf_path)
pdf_sign = ap.facades.PdfFileSignature(document)
pkcs = ap.forms.PKCS7Detached(cert, password, ap.DigestHashAlgorithm.SHA_3_256) # // ap.DigestHashAlgorithm.SHA_3_384, ap.DigestHashAlgorithm.SHA_3_512
pdf_sign.sign(1, True, drawing.Rectangle(300, 100, 400, 200), pkcs)
pdf_sign.save(output_pdf_path)
def verify(signed_pdf_file: str):
document = ap.Document(signed_pdf_file)
signature = ap.facades.PdfFileSignature(document)
sig_names = signature.get_sign_names(True)
for sig_name in sig_names:
is_valid = signature.verify_signature(sig_name)
What’s new in Aspose.PDF 24.12
The following snippet shows how to convert the annotation document to PDF/X-1 using the annotation FOGRA39 ICC profile:
import aspose.pdf as ap
def convert_pdf_to_pdf_x_1_using_custom_icc_profile(input_pdf_path: str, output_pdf_path: str):
document = ap.Document(input_pdf_path)
options = ap.PdfFormatConversionOptions(ap.PdfFormat.PDF_X_1A, ap.ConvertErrorAction.DELETE)
options.icc_profile_file_name = "Coated_Fogra39L_VIGC_300.icc"
options.output_intent = ap.OutputIntent("FOGRA39")
document.convert(options)
document.save(output_pdf_path)
The following sample shows how this can be used in PDF to PNG conversion to avoid text getting turned into blank squares:
import aspose.pdf as ap
def pdf_to_png_with_analyzing_fonts(input_pdf_path: str, output_pdf_path: str):
document = ap.Document(input_pdf_path)
png_device = ap.devices.PngDevice()
png_device.rendering_options = ap.RenderingOptions()
png_device.rendering_options.analyze_fonts = True
png_device.process(document.pages[1], output_pdf_path)
The following code snippet demonstrates how to add annotation text stamp to annotation PDF file and automatically adjust the font size to fit the stamp rectangle:
import aspose.pdf as ap
def auto_set_the_font_size_of_text_stamp(input_pdf_path: str, output_pdf_path: str):
document = ap.Document(input_pdf_path)
text = "Stamp example"
stamp = ap.TextStamp(text)
stamp.auto_adjust_font_size_to_fit_stamp_rectangle = True
stamp.auto_adjust_font_size_precision = 0.01
stamp.word_wrap_mode = ap.text.TextFormattingOptions.WordWrapMode.BY_WORDS
stamp.scale = False
stamp.width = 400
stamp.height = 200
document.pages[1].add_stamp(stamp)
document.save(output_pdf_path)
The following code snippet demonstrates how to add an annotation text stamp to an annotation PDF file and automatically adjust the font size to fit the page size:
import aspose.pdf as ap
def auto_set_the_font_size_of_text_stamp_to_fit_page(input_pdf_path: str, output_pdf_path: str):
document = ap.Document(input_pdf_path)
text = "Stamp example"
stamp = ap.TextStamp(text)
stamp.auto_adjust_font_size_to_fit_stamp_rectangle = True
stamp.auto_adjust_font_size_precision = 0.01
stamp.word_wrap_mode = ap.text.TextFormattingOptions.WordWrapMode.BY_WORDS
stamp.scale = False
document.pages[1].add_stamp(stamp)
document.save(output_pdf_path)