Browse our Products
Aspose.Words for Python via .NET 24.8 Release Notes
Major Features
There are 51 improvements and fixes in this regular monthly release. The most notable are:
- Chart Customization: Precise control over chart axis tick label orientation and rotation.
- Font Management: Expanded font information with EmbeddingLicensingRights property.
- Document Structure: Efficiently clear section headers and footers while preserving watermarks.
- Format Compatibility: Improved HTML and XAML export with backward compatibility for backslash and yen sign.
- PDF Functionality: Enhanced PDF export with support for using SDT tags as form field names.
- Document Conversion: Introduced a new LowCode.Converter class, designed to provide a set of methods for converting various types of documents with a single line of code.
- Digital Signatures: Enabled digital signing of XPS documents using XpsSaveOptions.
Full List of Issues Covering all Changes in this Release
Expand to view the full list of issues.
- Provide a way to specify UpdateCreatedTimeProperty,UpdateLastPrintedProperty and UpdateLastSavedTimeProperty options while using Document.RenderToSize and Document.RenderToScale methods
- Add property to specify axis labels orientation
- Add property to specify axis labels rotation
- Consider using Title or Tag of SDT as a name of form field in PDF
- Export control form tag or alias as form ID in PDF
- Consider adding an option into Section.ClearHeadersFooters to keep watermarks
- Implement low-code public API for direct conversion between fixed page formats
- Provide an option to check “Print and Preview” flag for fonts embedded into document
- Support watermarks in output XSLX documents
- Implement Bibliography edit API
- Provide Table.ConvertToText method in Aspose.Words
- Section breaks move to the next page and create blank pages when converting to PDF
- Providing sign document option in XpsSaveOptions
- Text positioning issue in list after converting PDF to DOCX
- Extra spaces between “THE” and “REGULAR”.
- Incorrect wrapping boundaries reported for a text box with auto width
- InvalidOperationException is thrown upon comparing document
- EQ field is rendered improperly
- Incorrect korean backslash symbol after converting to PDF
- Extra page while document saving to PDF
- Barcode generated by CustomBarcodeGenerator example has incorrect size
- Unneeded footnote continuation notice on conversion to PDF
- Remove obsolete API from IStructuredDocumentTag
- Table row
w14:paraId
are duplicated after cloning row - Second level items are not included in TOC
- Delta symbol in OfficeMath is rendered as missed character
- horizontal axis labels are rendered improperly after building report
- Italic text in OfficeMath is rendered as regular
- Incorrect font for Chinese characters inside SDT on conversion to PDF
- FileCorruptedException while loading mht files
- Style of footnote mark is lost after open/save RTF document
- Chart axis crossing value changed after re-saving
- Wrong layout when converting particular DOC to PDF
- pdf-online tool reports that PDF produced by Aspose.Words does not conform PDF 1.7 spec
- Reference to the Microsoft Forms 2.0 Object Library is lost after setting SourceCode
- Export to XLSX produces document with broken tables layout which can not be re-saved
- Chinese characters are rendered as missed characters
- Comment discrepancies after mapping
- Form fields are not updated after calling Document.UpdateFields
- Skatter chart is rendered improperly
- EQ-field matrix. Incorrect height
- Image loss after converting PDF to DOCX
- Axis boundaries are incorrect after building report
- Converting DOCX to RTF text disappears
- Bookmarks are not preserved in HtmlFixed
- Incorrect text wrapping when converting RTF to PDF
- Hyperlink Breakage in Aspose.Words PDF Conversion
- Wrong content alignment after conversion to HTML
- Skype SILK is detected by Aspose.Words as TXT
- Improve export of paragraphs with borders to HTML with embedded CSS
- Provide syntax analysis of text inside Html to auto-detect encoding
Public API and Backward Incompatible Changes
This section lists public API changes that were introduced in Aspose.Words for Python via .NET 24.8. It includes not only new and obsoleted public methods, but also a description of any changes in the behavior behind the scenes in Aspose.Words for Python via .NET which may affect existing code. Any behavior introduced that could be seen as regression and modifies the existing behavior is especially important and is documented here.
Added ability to set orientation and rotation of chart axis tick labels
The new properties orientation and rotation have been added to the AxisTickLabels class.
This use case explains how to to set orientation and rotation of axis tick labels:
doc = aw.Document()
builder = aw.DocumentBuilder(doc)
# Insert a column chart.
shape = builder.insert_chart(chart_type=aw.drawing.charts.ChartType.COLUMN, width=432, height=252)
x_tick_labels = shape.chart.axis_x.tick_labels
y_tick_labels = shape.chart.axis_y.tick_labels
# Set axis tick label orientation and rotation.
x_tick_labels.orientation = aw.drawing.ShapeTextOrientation.VERTICAL_FAR_EAST
x_tick_labels.rotation = -30
y_tick_labels.orientation = aw.drawing.ShapeTextOrientation.HORIZONTAL
y_tick_labels.rotation = 45
doc.save(file_name=ARTIFACTS_DIR + 'Charts.TickLabelsOrientationRotation.docx')
Added EmbeddingLicensingRights property to FontInfo and PhysicalFontInfo
Added embedding_licensing_rights property to FontInfo and PhysicalFontInfo classes.
This use case explains how to use embedding_licensing_rights:
settings = aw.fonts.FontSettings.default_instance
source = settings.get_fonts_sources()[0]
# Get the list of available fonts.
font_infos = source.get_available_fonts()
for font_info in font_infos:
if font_info.embedding_licensing_rights != None:
print(font_info.embedding_licensing_rights.embedding_usage_permissions)
print(font_info.embedding_licensing_rights.bitmap_embedding_only)
print(font_info.embedding_licensing_rights.no_subsetting)
Added new public method Section.ClearHeadersFooters(preserveWatermarks)
A new clear_headers_footers public method has been added to Section class.
This use case explains how to clear Headers and Footers but preserve the Watermarks:
doc = aw.Document(file_name=MY_DIR + 'Header and footer types.docx')
# Add a plain text watermark.
doc.watermark.set_text(text='Aspose Watermark')
# Make sure the headers and footers have content.
headers_footers = doc.first_section.headers_footers
self.assertEqual('First header', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.HEADER_FIRST).get_text().strip())
self.assertEqual('Second header', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.HEADER_EVEN).get_text().strip())
self.assertEqual('Third header', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.HEADER_PRIMARY).get_text().strip())
self.assertEqual('First footer', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.FOOTER_FIRST).get_text().strip())
self.assertEqual('Second footer', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.FOOTER_EVEN).get_text().strip())
self.assertEqual('Third footer', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.FOOTER_PRIMARY).get_text().strip())
# Removes all header and footer content except watermarks.
doc.first_section.clear_headers_footers(True)
headers_footers = doc.first_section.headers_footers
self.assertEqual('', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.HEADER_FIRST).get_text().strip())
self.assertEqual('', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.HEADER_EVEN).get_text().strip())
self.assertEqual('', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.HEADER_PRIMARY).get_text().strip())
self.assertEqual('', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.FOOTER_FIRST).get_text().strip())
self.assertEqual('', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.FOOTER_EVEN).get_text().strip())
self.assertEqual('', headers_footers.get_by_header_footer_type(aw.HeaderFooterType.FOOTER_PRIMARY).get_text().strip())
self.assertEqual(aw.WatermarkType.TEXT, doc.watermark.type)
# Removes all header and footer content including watermarks.
doc.first_section.clear_headers_footers(False)
self.assertEqual(aw.WatermarkType.NONE, doc.watermark.type)
Added ReplaceBackslashWithYenSign backward compatibility options to HtmlSaveOptions and XamlFlowSaveOptions
Added replace_backslash_with_yen_sign property to HtmlSaveOptions and to XamlFlowSaveOptions. It designed for keep backward compatibility with previous versions of Aspose.Words and allows to replace a backslash character with Yen sign in generated HTML and XAML documents.
This use case explains how to replace a backslash character with Yen sign in generated HTML document:
doc = aw.Document(file_name=MY_DIR + 'Korean backslash symbol.docx')
# By default, Aspose.Words mimics MS Word's behavior and doesn't replace backslash characters with yen signs in
# generated HTML documents. However, previous versions of Aspose.Words performed such replacements in certain
# scenarios. This flag enables backward compatibility with previous versions of Aspose.Words.
save_options = aw.saving.HtmlSaveOptions()
save_options.replace_backslash_with_yen_sign = True
doc.save(file_name=ARTIFACTS_DIR + 'HtmlSaveOptions.ReplaceBackslashWithYenSign.html', save_options=save_options)
This use case explains how to replace a backslash character with Yen sign in generated XAML document:
doc = aw.Document(file_name=MY_DIR + "Korean backslash symbol.docx")
# By default, Aspose.Words mimics MS Word's behavior and doesn't replace backslash characters with yen signs in
# generated HTML documents. However, previous versions of Aspose.Words performed such replacements in certain
# scenarios. This flag enables backward compatibility with previous versions of Aspose.Words.
save_options = aw.saving.XamlFlowSaveOptions()
save_options.replace_backslash_with_yen_sign = True
doc.save(file_name=ARTIFACTS_DIR + "HtmlSaveOptions.ReplaceBackslashWithYenSign.xaml", save_options=save_options)
Added UseSdtTagAsFormFieldName property to PdfSaveOptions
Added use_sdt_tag_as_form_field_name property to PdfSaveOptions. It allows to use StructuredDocumentTag.tag as a PDF form field name instead of StructuredDocumentTag.id. Also now StructuredDocumentTag.title field is exported as PDF form field user name.
This use case explains how to use UseSdtTagAsFormFieldName property:
doc = aw.Document(file_name=MY_DIR + 'Form fields.docx')
save_options = aw.saving.PdfSaveOptions()
save_options.preserve_form_fields = True
# When set to 'false', SDT control Id property is used as a name of form field in PDF.
# When set to 'true', SDT control Tag property is used as a name of form field in PDF.
save_options.use_sdt_tag_as_form_field_name = True
doc.save(file_name=ARTIFACTS_DIR + 'PdfSaveOptions.SdtTagAsFormFieldName.pdf', save_options=save_options)
Introduced a new LowCode.Converter class, designed to provide a set of methods for converting various types of documents with a single line of code
Introduced a new LowCode.Converter class, designed to provide a set of methods for converting various types of documents with a single line of code.
This use case explains how to convert the given input document into the output document using specified input output file names, save format or save options:
aw.lowcode.Converter.convert(input_file=MY_DIR + 'Document.docx', output_file=ARTIFACTS_DIR + 'LowCode.Convert.pdf')
aw.lowcode.Converter.convert(input_file=MY_DIR + 'Document.docx', output_file=ARTIFACTS_DIR + 'LowCode.Convert.rtf', save_format=aw.SaveFormat.RTF)
save_options = aw.saving.OoxmlSaveOptions()
save_options.password = 'Aspose.Words'
aw.lowcode.Converter.convert(input_file=MY_DIR + 'Document.doc', output_file=ARTIFACTS_DIR + 'LowCode.Convert.docx', save_options=save_options)
first_file_in = open(MY_DIR + 'Big document.docx', mode='rb')
first_stream_in = io.BytesIO(first_file_in.read())
out = io.BytesIO()
aw.lowcode.Converter.convert(first_stream_in, out, aw.SaveFormat.DOCX)
out.flush()
pathlib.Path(ARTIFACTS_DIR + 'LowCode.ConvertStream.SaveFormat.docx').write_bytes(out.getvalue())
out.seek(0)
save_options = aw.saving.OoxmlSaveOptions()
save_options.password = "Aspose.Words"
aw.lowcode.Converter.convert(first_stream_in, out, save_options)
out.flush()
pathlib.Path(ARTIFACTS_DIR + 'LowCode.ConvertStream.SaveOptions.docx').write_bytes(out.getvalue())
out.close()
first_stream_in.close()
first_file_in.close()
The convert_to_images group of methods are designed to transform documents into images, with each page being converted into a separate image file. These methods also convert PDF documents directly to fixed-page formats without loading them into the document model (using our pdf2word plugin), which enhances both performance and accuracy.
Using ImageSaveOptions.page_set, you can specify a particular set of pages to convert into images.
aw.lowcode.Converter.convert_to_images(input_file=MY_DIR + 'Big document.docx', output_file=ARTIFACTS_DIR + 'LowCode.ConvertToImages.png')
aw.lowcode.Converter.convert_to_images(input_file=MY_DIR + 'Big document.docx', output_file=ARTIFACTS_DIR + 'LowCode.ConvertToImages.jpeg', save_format=aw.SaveFormat.JPEG)
image_save_options = aw.saving.ImageSaveOptions(aw.SaveFormat.PNG)
image_save_options.page_set = aw.saving.PageSet(page=1)
aw.lowcode.Converter.convert_to_images(input_file=MY_DIR + 'Big document.docx', output_file=ARTIFACTS_DIR + 'LowCode.ConvertToImages.png', save_options=image_save_options)
first_file_in = open(MY_DIR + 'Big document.docx', mode='rb')
first_stream_in = io.BytesIO(first_file_in.read())
streams = aw.lowcode.Converter.convert_to_images(first_stream_in, aw.SaveFormat.JPEG)
save_options = aw.saving.ImageSaveOptions(aw.SaveFormat.PNG)
save_options.page_set = aw.saving.PageSet(1)
streams = aw.lowcode.Converter.convert_to_images(first_stream_in, save_options)
streams = aw.lowcode.Converter.convert_to_images(input_file=MY_DIR + 'Big document.docx', save_format=aw.SaveFormat.PNG)
image_save_options = aw.saving.ImageSaveOptions(aw.SaveFormat.PNG)
image_save_options.page_set = aw.saving.PageSet(page=1)
streams = aw.lowcode.Converter.convert_to_images(input_file=MY_DIR + 'Big document.docx', save_options=image_save_options)
streams = aw.lowcode.Converter.convert_to_images(doc=aw.Document(file_name=MY_DIR + 'Big document.docx'), save_format=aw.SaveFormat.PNG)
streams = aw.lowcode.Converter.convert_to_images(doc=aw.Document(file_name=MY_DIR + 'Big document.docx'), save_options=image_save_options)
Provided sign document option in XpsSaveOptions
Added new public property digital_signature_details added to Aspose.Words.Saving.XpsSaveOptions class.
This use case explains how to specify signature options while saving XPS document:
doc = aw.Document(file_name=MY_DIR + 'Document.docx')
certificate_holder = aw.digitalsignatures.CertificateHolder.create(file_name=MY_DIR + 'morzal.pfx', password='aw')
options = aw.digitalsignatures.SignOptions()
options.sign_time = datetime.datetime.now()
options.comments = 'Some comments'
digital_signature_details = aw.saving.DigitalSignatureDetails(certificate_holder, options)
save_options = aw.saving.XpsSaveOptions()
save_options.digital_signature_details = digital_signature_details
self.assertEqual(certificate_holder, digital_signature_details.certificate_holder)
self.assertEqual('Some comments', digital_signature_details.sign_options.comments)
doc.save(file_name=ARTIFACTS_DIR + 'XpsSaveOptions.XpsDigitalSignature.docx', save_options=save_options)
Removed obsolete API from IStructuredDocumentTag
The obsolete public methods is_ranged() and structured_document_tag_node() have been removed from IStructuredDocumentTag interface and all its implementations.
Please note that the removed is_ranged() is equivalent to is_multi_section property, and the removed structured_document_tag_node() is equivalent to node property. Please use these properties instead.