Aspose.Words for .NET 21.1 Release Notes
Major Features
There are 78 improvements and fixes in this regular monthly release. The most notable are:
- StartColumnBookmark and EndColumnBookmark methods were introduced in DocumentBuilder class.
- MarkdownSaveOptions.ImageSavingCallback has been added to control how images are saved upon converting to Markdown format.
- Added an ability to ignore <noscript> HTML elements upon loading HTML.
- TableStyle.VerticalAlignment was exposed publicly.
Full List of Issues Covering all Changes in this Release
Key | Summary | Category |
---|---|---|
WORDSNET-4987 | Support “cold” rendering of OOXML SmartArt (Diagrams) | New Feature |
WORDSNET-20666 | Add feature to create Move revision | New Feature |
WORDSNET-21389 | Add IImageSavingCallback into MarkdownSaveOptions | New Feature |
WORDSNET-17026 | LINQ Reporting Engine - Support section breaks inside data bands and conditional blocks | New Feature |
WORDSNET-20367 | Add a field to the Node class so a User can store some custom meta-data in Aspose.Words Document model | New Feature |
WORDSNET-18882 | Add feature to bookmark the table’s column | New Feature |
WORDSNET-21114 | Add feature to get or set Cell Vertical Alignment using TableStyle | New Feature |
WORDSNET-21426 | MS Word should automatically pick default Icon of Inserted OLE Object | Enhancement |
WORDSNET-21576 | Add LastChild property and AppendChild() method to StructuredDocumentRangeStart class | Enhancement |
WORDSNET-21433 | Improve URI processing to handle relative hyperlink | Enhancement |
WORDSNET-21493 | Convert Word to JSON in Parent Child Hierarchy | Enhancement |
WORDSNET-20881 | Partial rendering of Arabic Words in PDF | Bug |
WORDSNET-21005 | Document.PageCount hangs for MHTML file generated by Aspose.Email | Bug |
WORDSNET-18933 | DOCX to PDF conversion issue with math equation | Bug |
WORDSNET-15142 | Incorrect page count detection | Bug |
WORDSNET-21516 | First column content spilling into second column in PDF | Bug |
WORDSNET-17876 | Characters (subset) in charts are not rendered in output PDF | Bug |
WORDSNET-13179 | DOCX to PDF conversion issue with text rendering of Cambodian Fonts “Khmer” | Bug |
WORDSNET-18333 | Superscript and Subscript characters in picture are not retained in PDF | Bug |
WORDSNET-21191 | InvalidOperationException occurs during saving to HTML | Bug |
WORDSNET-16704 | BitonalConvertor gives not the same result as on .NET | Bug |
WORDSNET-17362 | Brackets and equation rendering issue in output PDF | Bug |
WORDSNET-21509 | DOCX to PDF conversion exception: System.ArgumentOutOfRangeException | Bug |
WORDSNET-21415 | Document.Compare generates the incorrect output | Bug |
WORDSNET-17888 | Arabic characters are improperly rendered to another font | Bug |
WORDSNET-17986 | Position of BookmarkStart and BookmarkEnd nodes is changed in output DOCX | Bug |
WORDSNET-21534 | Incorrect value of STYLEREF field in header - Word to PDF Conversion | Bug |
WORDSNET-21535 | Aspose.Words.FileCorruptedException is thrown for DOC | Bug |
WORDSNET-21462 | DOCX to HTML conversion fails with Stack empty error message | Bug |
WORDSNET-21506 | Hidden runs located in a Structured Document tag cannot be iterated | Bug |
WORDSNET-20715 | The conversion to PDF never ends | Bug |
WORDSNET-21510 | System.ArgumentOutOfRangeException occurs upon saving to PDF | Bug |
WORDSNET-21519 | DOCX to PDF conversion exception | Bug |
WORDSNET-21494 | Document.UpdateFields throws NullReferenceException | Bug |
WORDSNET-20010 | Infinity loop in FloaterOverlapResolver due to zero height floating table | Bug |
WORDSNET-21545 | Add obfuscation check to ApiTests.License.Net task | Bug |
WORDSNET-21552 | Incorrect identification of list level and list item | Bug |
WORDSNET-17735 | Certain Arabic characters are wrong when converting DOCX to PDF | Bug |
WORDSNET-20166 | Infinity loop in FloaterOverlapResolver | Bug |
WORDSNET-18940 | Conversion issue DOC/DOCX to PDF | Bug |
WORDSNET-17428 | Superscript and Subscript characters in Picture render as question mark in PDF | Bug |
WORDSNET-21579 | Insert SVG image failed on .NetFramework | Bug |
WORDSNET-21434 | DOCX to PDF conversion: The numbering issue in the output | Bug |
WORDSNET-21253 | Unexpected chart type | Bug |
WORDSNET-20876 | SmartArt to PNG conversion issue with wrong background color and wrong font | Bug |
WORDSNET-21443 | LINQ Reporting Engine - An issue with a JSON object having only complex properties | Bug |
WORDSNET-20892 | ODT to Html: Frame borders and position are lost when converting .odt to html | Bug |
WORDSNET-21116 | PDF/A-1a fails accessibility check | Bug |
WORDSNET-3814 | Line numbering shows up in OpenOffice after changing PageSetup settings | Bug |
WORDSNET-21419 | Inline ole shape overlaps container cell border after DOCX to PDF conversion | Bug |
WORDSNET-21325 | Comments date do not reflect to changed time zone | Bug |
WORDSNET-21453 | “Arithmetic operation resulted in an overflow.” exception when converting DOCX file to PNG/HTML/PDF | Bug |
WORDSNET-20954 | Table lost formatting on page extraction | Bug |
WORDSNET-21268 | DOC to PDF conversion hangs | Bug |
WORDSNET-21460 | Bibliography text disappears during conversion | Bug |
WORDSNET-21153 | UpdatePageLayout is throwing Array Dimensions exceeded supported range | Bug |
WORDSNET-20681 | OutOfMemoryException when SaveAs document as PNG | Bug |
WORDSNET-21173 | No content is loaded from a CHM file | Bug |
WORDSNET-21282 | Preserve Text Alignment in Table Cell during Word DOT to HTML Conversion | Bug |
WORDSNET-21286 | DataLabel customization does not work when chart is inserted into template | Bug |
WORDSNET-21171 | FileCorruptedException is thrown when trying to load a CHM document | Bug |
WORDSNET-21299 | Sunburst Chart DOCX to PDF - System.ArgumentException Unexpected chart type | Bug |
WORDSNET-21476 | Aspose.Words corrupts document containing statistical chart | Bug |
WORDSNET-21481 | Comment.DateTime get time in UTC without conversion to local | Bug |
WORDSNET-21326 | Execution of the Aspose.Words hangs on Linux when Tahoma font is absent | Bug |
WORDSNET-21203 | HTML to PDF output incomplete | Bug |
WORDSNET-21341 | 3rd level of Thai text is not shown and replaced by strange symbol - DOCX to PDF | Bug |
WORDSNET-19932 | Number list issues while converting DOCX -> HTML -> DOCX | Bug |
WORDSNET-21216 | Diffrent behavior of “=SUM(ABOVE)” compared to Microsoft Word | Bug |
WORDSNET-21366 | DOC->PDF conversion: Heading loses capitalization and bold effect in the output | Bug |
WORDSNET-16770 | Image’s text is rendered as “?” mark in output PDF | Bug |
WORDSNET-14872 | Lack of CSS background images while converting from HTML to Word | Bug |
WORDSNET-16336 | Khmer Mondulkiri font renders incorrectly | Bug |
WORDSNET-17887 | Arial Font is used instead of Calibri Fonts during DOCM to PDF conversion | Bug |
WORDSNET-16703 | TestRadialGradient is rendered improperly. | Bug |
WORDSNET-11650 | System.NullReferenceException is thrown while saving DOCX to PDF | Bug |
WORDSNET-19294 | TestLoadPerformanceLarge() performance test fails | Bug |
WORDSNET-16717 | Background in MHT looks differently | Bug |
Public API and Backward Incompatible Changes
This section lists public API changes that were introduced in Aspose.Words 21.1. 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 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 a new public property HtmlLoadOptions.IgnoreNoscriptElements
Related issue: WORDSNET-21203
Added a new public property HtmlLoadOptions.IgnoreNoscriptElements:
/// <summary>
/// Gets or sets a value indicating whether to ignore <noscript> HTML elements.
/// Default value is <c>false</c>.
/// </summary>
/// <remarks>
/// Like MS Word, Aspose.Words does not support scripts and by default loads content of <noscript> elements
/// into the resulting document. In most browsers, however, scripts are supported and content from <noscript>
/// is not visible. Setting this property to <c>true</c> forces Aspose.Words to ignore all <noscript> elements
/// and helps to produce documents that look closer to what is seen in browsers.
/// </remarks>
public bool IgnoreNoscriptElements { get; set; }
Customers may now instruct Aspose.Words to ignore <noscript> HTML elements like most modern browsers do.
Use Case:
HtmlLoadOptions loadOptions = new HtmlLoadOptions();
loadOptions.IgnoreNoscriptElements = true;
Added a new public property Node.CustomNodeId
Related issue: WORDSNET-21203
Added a new public property Node.CustomNodeId:
/// <summary>
/// Specifies custom node identifier.
/// </summary>
/// <remarks>
/// <p>Default is zero.</p>
/// <p>This identifier can be set and used arbitrarily. For example, as a key to get external data.</p>
/// </remarks>
public int CustomNodeId { get; set; }
Customers now may track node position in the model tree and bind external data based on assigned identifier:
Use Case:
DocumentBuilder builder = new DocumentBuilder();
Shape shape = builder.InsertShape(ShapeType.Rectangle, 100, 100);
shape.CustomNodeId = 100;
Added a new public property TableStyle.VerticalAlignment
Related issue: WORDSNET-21114
Added a new public options that allows to set table style cell vertical alignment.
/// <summary>
/// Specifies the vertical alignment for the cells.
/// </summary>
/// <remarks>
/// The default value is <see cref="CellVerticalAlignment.Top"/>.
/// </remarks>
public CellVerticalAlignment VerticalAlignment { get; set; }
Use Case:
Document doc = TestUtil.Open(fileName);
TableStyle style = (TableStyle)doc.Styles\["Custom Table 1"\];
style.VerticalAlignment = CellVerticalAlignment.Center;
Added new public methods StartColumnBookmark and EndColumnBookmark to DocumentBuilder class
Related issue: WORDSNET-18882
The following public methods have been added to the DocumentBuilder class:
/// <summary>
/// Marks the current position in the document as a column bookmark start. The position must be in a table cell.
/// </summary>
/// <remarks>
/// <p>A column bookmark covers one or more columns in a range of rows. To create a valid bookmark you
/// need to call both <see cref="StartColumnBookmark"/> and <see cref="EndColumnBookmark"/> with the same
/// <b>bookmarkName</b> parameter.</p>
/// <p>Badly formed bookmarks or bookmarks with duplicate names will be ignored when the document is saved.</p>
/// <p>The actual position of the inserted <see cref="BookmarkStart"/> node may differ from the current document
/// builder position.</p>
/// </remarks>
/// <param name="bookmarkName">Name of the bookmark.</param>
/// <returns>The bookmark start node that was just created.</returns>
public BookmarkStart StartColumnBookmark(string bookmarkName)
/// <summary>
/// Marks the current position in the document as a column bookmark end. The position must be in a table cell.
/// </summary>
/// <remarks>
/// <p>A column bookmark covers one or more columns in a range of rows. To create a valid bookmark you
/// need to call both <see cref="StartColumnBookmark"/> and <see cref="EndColumnBookmark"/> with the same
/// <b>bookmarkName</b> parameter.</p>
/// <p>Badly formed bookmarks or bookmarks with duplicate names will be ignored when the document is saved.</p>
/// <p>The actual position of the inserted <see cref="BookmarkEnd"/> node may differ from the current document
/// builder position.</p>
/// </remarks>
/// <param name="bookmarkName">Name of the bookmark.</param>
/// <returns>The bookmark end node that was just created.</returns>
public BookmarkEnd EndColumnBookmark(string bookmarkName)
Use Case:
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.StartTable();
builder.InsertCell();
builder.StartColumnBookmark("Bookmark1");
builder.Write("Cell 1");
builder.InsertCell();
builder.Write("Cell 2");
builder.InsertCell();
builder.Write("Cell 3");
builder.EndRow();
builder.InsertCell();
builder.Write("Cell 4");
builder.InsertCell();
builder.Write("Cell 5");
builder.EndColumnBookmark("Bookmark1");
builder.InsertCell();
builder.Write("Cell 6");
builder.EndRow();
builder.EndTable();
doc.Save(dir + "out.docx");
MarkdownSaveOptions.ImageSavingCallback has been added to control how images are saved upon converting to Markdown format
Related issue: WORDSNET-21389
A new public property ‘ImageSavingCallback’ has been added to the ‘MarkdownSaveOptions’ class:
/// <summary>
/// Allows to control how images are saved when a document is saved to <see cref="SaveFormat.Markdown"/> format.
/// </summary>
public IImageSavingCallback ImageSavingCallback
Use Case: Explains how to use ‘MarkdownSaveOptions.ImageSavingCallback’ when saving a document to markdown format
public void HandleDocument()
{
const string outFileName = "SavingCallback.DocumentParts.Rendering.md";
// Open a document to be converted to Markdown.
Document doc = new Document("C:\\Rendering.docx");
// We can use an appropriate SaveOptions subclass to customize the conversion process.
MarkdownSaveOptions options = new MarkdownSaveOptions();
// If we convert a document that contains images into Markdown, we will end up with one Markdown file which links to several images.
// Each image will be in the form of a file in the local file system.
// There is also a callback that can customize the name and file system location of each image.
options.ImageSavingCallback = new SavedImageRename(outFileName);
// The ImageSaving() method of our callback will be run at this time.
doc.Save($"C:\\{outFileName}", options);
}
/// <summary>
/// Renames saved images that are produced when an Markdown document is saved.
/// </summary>
public class SavedImageRename : IImageSavingCallback
{
public SavedImageRename(string outFileName)
{
mOutFileName = outFileName;
}
void IImageSavingCallback.ImageSaving(ImageSavingArgs args)
{
string imageFileName = $"{mOutFileName} shape {++mCount}, of type {args.CurrentShape.ShapeType}{Path.GetExtension(args.ImageFileName)}";
args.ImageFileName = imageFileName;
args.ImageStream = new FileStream($"C:\\{imageFileName}", FileMode.Create);
Assert.True(args.ImageStream.CanWrite);
Assert.True(args.IsImageAvailable);
Assert.False(args.KeepImageStreamOpen);
}
private int mCount;
private readonly string mOutFileName;
}
PdfSaveOptions.EscapeUri is marked as obsolete
We made several improvements in export of hyperlinks to PDF per WORDSNET-21443. Now the cases when setting PdfSaveOptions.EscapeUri to false was required (improper unescaping of explicitly escaped URI delimiter chars) are handled well by default. Thus we do not see a reason to keep this option longer and marked it as obsolete.
/// <summary>
/// A flag specifying whether URI should be escaped before writing.
/// </summary>
/// <remarks>
/// Note that if this option is set to <c>false</c> hyperlinks are written "as is",
/// so valid (escaped) URI should be provided in document's model.
/// <para>The default value is <c>true</c>.</para>
/// </remarks>
[Obsolete("Writing of URI to PDF was improved and cases when disabled escaping was required are handled well now.")]
public bool EscapeUri { get; set; }
Removed obsolete properties FixedPageSaveOptions.PageIndex, FixedPageSaveOptions.PageCount, ImageSaveOptions.PageIndex, ImageSaveOptions.PageCount
Related issue: WORDSNET-21154
Deprecated properties related to page specification when printing were removed from the FixedPageSaveOptions and ImageSaveOptions classes.
[Obsolete("This property is obsolete. Please use PageSet property instead.")]
public new int PageCount
[Obsolete("This property is obsolete. Please use PageSet property instead.")]
public new int PageIndex
The behavior of DocumentBuilder.InsertOleObject() and DocumentBuilder.InsertOleObjectAsIcon() methods was changed
Related issue: WORDSNET-21426
In cases where the DocumentBuilder.InsertOleObject() and DocumentBuilder.InsertOleObjectAsIcon() methods need to create an icon with a caption, they can use the file extension to define the icon, and can use the filename for the icon caption.
More details:
public Shape InsertOleObject(Stream stream, string progId, bool asIcon, Stream presentation)
public Shape InsertOleObject(string fileName, bool isLinked, bool asIcon, Stream presentation)
public Shape InsertOleObject(string fileName, string progId, bool isLinked, bool asIcon, Stream presentation)
public Shape InsertOleObjectAsIcon(Stream stream, string progId, string iconFile, string iconCaption)
public Shape InsertOleObjectAsIcon(string fileName, string progId, bool isLinked, string iconFile, string iconCaption)
public Shape InsertOleObjectAsIcon(string fileName, bool isLinked, string iconFile, string iconCaption)
Changed XML comments for ‘iconCaption’ arguments of DocumentBuilder.InsertOleObjectAsIcon() methods:
/// <summary>
/// Inserts an embedded or linked OLE object as icon into the document.
/// Allows to specify icon file and caption. Detects OLE object type using file extension.
/// </summary>
/// <param name="fileName">Full path to the file.</param>
/// <param name="isLinked">
/// If true then linked OLE object is inserted otherwise embedded OLE object is inserted.
/// </param>
/// <param name="iconFile">
/// Full path to the ICO file. If the value is null, Aspose.Words will use a predefined image.
/// </param>
/// <param name="iconCaption">
/// Icon caption. If the value is null, Aspose.Words will use the file name.
/// </param>
/// <returns>Shape node containing Ole object and inserted at the current Builder position.</returns>
public Shape InsertOleObjectAsIcon(string fileName, bool isLinked, string iconFile, string iconCaption)
/// <summary>
/// Inserts an embedded or linked OLE object as icon into the document.
/// Allows to specify icon file and caption. Detects OLE object type using given progID parameter.
/// </summary>
/// <param name="fileName">Full path to the file.</param>
/// <param name="progId">ProgId of OLE object.</param>
/// <param name="isLinked">
/// If true then linked OLE object is inserted otherwise embedded OLE object is inserted.
/// </param>
/// <param name="iconFile">
/// Full path to the ICO file. If the value is null, Aspose.Words will use a predefined image.
/// </param>
/// <param name="iconCaption">
/// Icon caption. If the value is null, Aspose.Words will use the file name.
/// </param>
/// <returns>Shape node containing Ole object and inserted at the current Builder position.</returns>
public Shape InsertOleObjectAsIcon(string fileName, string progId, bool isLinked, string iconFile, string iconCaption)
/// <summary>
/// Inserts an embedded OLE object as icon from a stream into the document.
/// Allows to specify icon file and caption. Detects OLE object type using given progID parameter.
/// </summary>
/// <param name="stream">Stream containing application data.</param>
/// <param name="progId">ProgId of OLE object.</param>
/// <param name="iconFile">
/// Full path to the ICO file. If the value is null, Aspose.Words will use a predefined image.
/// </param>
/// <param name="iconCaption">
/// Icon caption. If the value is null, Aspose.Words will use the a predefined icon caption.
/// </param>
/// <returns>Shape node containing Ole object and inserted at the current Builder position.</returns>
public Shape InsertOleObjectAsIcon(Stream stream, string progId, string iconFile, string iconCaption)
The behavior of revision tracking feature triggered by Document.StartTrackRevisions was changed
Related issue: WORDSNET-20666
When revisions are tracked using Document.StartTrackRevisions, if a node is moved from one location to another in the same document, move revisions are now generated, including move-from and move-to ranges.
Use Case:
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Generate document contents.
builder.Writeln("Paragraph 1");
builder.Writeln("Paragraph 2");
builder.Writeln("Paragraph 3");
builder.Writeln("Paragraph 4");
builder.Writeln("Paragraph 5");
builder.Writeln("Paragraph 6");
Body body = doc.FirstSection.Body;
// Returns 7.
Console.WriteLine("Paragraph count: {0}", body.Paragraphs.Count);
doc.StartTrackRevisions("Author", new DateTime(2020, 12, 23, 14, 0, 0));
Node node = body.Paragraphs[3];
Node endNode = body.Paragraphs[5].NextSibling;
Node referenceNode = body.Paragraphs[0];
while (node != endNode)
{
Node nextNode = node.NextSibling;
body.InsertBefore(node, referenceNode);
node = nextNode;
}
doc.StopTrackRevisions();
// Returns 10: there are 3 additional paragraphs in the move-from range.
Console.WriteLine("Paragraph count: {0}", body.Paragraphs.Count);
doc.Save(dir + @"out.docx");