Aspose.Words for Java 19.6 Release Notes

Major Features

  • Improved loading license in multi-thread environment.
  • Provided API to Extract VBA Macros from Word Document.
  • Added a new DocSaveOptions.AlwaysCompressMetafiles option.
  • Implemented table style public API.
  • Improved rendering of CurvedArrow shapes with basic and custom adjustment points.
  • Improved rendering of DrawingML charts with scaling of the vertical axis if the chart legend has a manual layout.
  • FontInfo substitution was tuned to prefer symbolic fonts as a substitution for symbolic fonts and regular fonts as a substitution for regular fonts. This fixes the customer issue with selecting symbolic “XVMSymbol” font as a substitution for a regular font.
  • Fixed a bug with scale changing when rendering DrawingML charts.
  • Fixed a bug with text inner shadow rendering when converting to HTML.
  • Fixed a bug with Stacked Area Chart rendering, if the series has a different number of values.
  • Fixed a bug with a second empty chart with hidden axes.
  • Fixed a bug with missing vowel glyph when rendering Thai fonts.
  • Fixed issue with incorrect calculation of start and closing points for small ellipses when rendering DrawingML objects.
  • Fixed table grid calculation issue when the auto table has pct width mixed with %.
  • Fixed exception when table which spans multiple pages and has many nested floaters is broken across pages.
  • Improved text positioning when there is a paragraph-relative shape with an anchor wrapped around multiple floaters.
  • Improved calculation of space before a paragraph when it’s first in the document and there is a floater before it.

Full List of Issues Covering all Changes in this Release

KeySummaryCategory
WORDSNET-5312Support creating table stylesNew Feature
WORDSNET-17604Provide a way to access Cell Padding properties of a specific TableStyleNew Feature
WORDSNET-18570Horizontally Merged Cells are not IdentifiedNew Feature
WORDSNET-17757Provide API to Extract VBA Macros from Word DocumentNew Feature
WORDSNET-18400Add feature to modify the table stylesNew Feature
WORDSNET-3714Consider adding an ability to read macros from documentsNew Feature
WORDSNET-18473Implement switching between Software and Hardware modes renderingNew Feature
WORDSNET-9641Accessing information of Table StylesNew Feature
WORDSJAVA-2006Colour shading Issue in PDFBug
WORDSJAVA-2062Does not load <img> src containing Chinese characters.Bug
WORDSJAVA-2084Chart axis label format code.Bug
WORDSJAVA-2085Some ApsPath FillMode is not supported.Bug
WORDSJAVA-2086Exception throws during loading a malformed image.Bug
WORDSJAVA-2088PageSetup returns A4 PaperSize instead of Letter for En-US locale.Bug
WORDSJAVA-2089License.setLicense throws NullPointerException when running in a multi-threaded environment.Bug
WORDSJAVA-2090Aspose words 18.10 or above produce PDF with red evaluation ASPOSE watermark in a multi-threaded environment.Bug
WORDSJAVA-2091NullPointerException in VerificationSupervisor in a highly concurrent multithreaded environmentBug
WORDSJAVA-2101OLE icon’s text is blurred after conversion to HTML.Bug
WORDSNET-18372System.NullReferenceException occurs upon calling Document.UpdateFields methodBug
WORDSNET-18556System.IndexOutOfRangeException occurs during renderingBug
WORDSNET-18407Table.AutoFit does not work for AutoFitBehavior.AutoFitToWindowBug
WORDSNET-18566After conversion .rtf to PDF - part of the text is missingBug
WORDSNET-16363SVG gradient issuesBug
WORDSNET-18414UpdateFields stopped adding page numbers after upgrading to v19.3 for .NetBug
WORDSNET-18572Document.UpdateFields does not update the TOC fieldBug
WORDSNET-18574Document.CopyStylesFromTemplate throws System.NullReferenceExceptionBug
WORDSNET-18443DOCX to PDF/HTMLFixed conversion issue with Shapes (Arrows) positionBug
WORDSNET-18508Cell border and width is changed after conversion from RTF to DOCXBug
WORDSNET-18206DOCX to PDF - text is moved downBug
WORDSNET-17470The scale of charts changes during renderingBug
WORDSNET-17468The scale of charts changes during renderingBug
WORDSNET-17856Remove obsolete methods Replace() from the Range classBug
WORDSNET-18388Document.UpdateFields throws System.ArgumentExceptionBug
WORDSNET-17566System.OutOfMemoryException is thrown while saving DOCX to HTMLBug
WORDSNET-18079Converting .docx to pdf shifts the text box down on the pageBug
WORDSNET-16544Extra lines are rendered in output PDFBug
WORDSNET-18555System.NullReferenceException occurs during renderingBug
WORDSNET-18061Image scaling problem during export to SVGBug
WORDSNET-18557Shading.BackgroundPatternColor returns incorrect cell’s background colorBug
WORDSNET-18586Failed tests with error: “Parameter is not valid.”Bug
WORDSNET-18587Incorrect rendering of CurvedArrows with custom adjustment valuesBug
WORDSNET-18276DOCX to HtmlFixed conversion issue with TOC itemsBug
WORDSNET-18575Incorrect font substitution for Helvetica Neue fontBug
WORDSNET-18602FileCorruptedException occurs upon loading DOCBug
WORDSNET-18579Lists.Count returns incorrect value after calling Document.CleanupBug
WORDSNET-18554SVG text alignment is rendered incorrectBug
WORDSNET-18517System.NullReferenceException occurs when saving to PDFBug
WORDSNET-18604Glossary document style changed after savingBug
WORDSNET-13116Content controls are missed after saving Docx to Doc/PdfBug
WORDSNET-18233Issues with table width in pdfBug
WORDSNET-13769A table row not visible in AW pdf outputBug
WORDSNET-18232The empty paragraph is lost during HTML round-tripBug
WORDSNET-18520Accept tracking changes takes too long to completeBug
WORDSNET-18421DOCX to PDF conversion issue with QR codeBug
WORDSNET-15459Docx to Pdf conversion issue with text positionBug
WORDSNET-16290Text inserted with DocumentBuilder.InsertHtml has the wrong font familyBug
WORDSNET-18059DocumentBuilder.InsertImage inserts the SVG incorrectly in documentBug
WORDSNET-14480MathML has spaces between numbers in output Html/DocxBug
WORDSNET-18476Document.UpdateFields throws System.ArgumentExceptionBug
WORDSNET-18551Incorrect rendering of CurvedArrows when converting to HTMLBug
WORDSNET-18112Fields Containing Content Controls Not UpdatedBug
WORDSNET-17867Axis labels changed during Docx to  PDF conversionBug
WORDSNET-18481System.ArgumentOutOfRangeException is thrown while saving DOCX to PDFBug
WORDSNET-18168The formula in Doc file corrupted when opening with LibreOfficeBug
WORDSNET-18497Watermark does not show vowel glyph when saving to pdfBug
WORDSNET-18638Improve DML comparisonBug
WORDSNET-18640Incorrect WordArt rendering with shadow effectBug
WORDSNET-18645Images are imported incorrectly in Aspose.Words DOMBug
WORDSNET-18616Missing text in word to pdf renderingBug
WORDSNET-13064Content controls are missed after saving Docx to Doc/PdfBug

Public API and Backward Incompatible Changes

This section lists public API changes that were introduced in Aspose.Words 19.6. 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 existing behavior is especially important and is documented here.

Added a new DocSaveOptions.AlwaysCompressMetafiles option

Related issue: WORDSNET-18202.

Large metafiles are always compressed when exporting a document. But small metafiles are not compressed for performance reason. Word compresses all metafiles regardless of its size. Also, some other document editors, such as LibreOffice, cannot read uncompressed metafiles. To allow users to choose an appropriate behavior, the following option was introduced in DocSaveOptions class:

/// <summary>
/// When <c>false</c>, small metafiles are not compressed for performance reason.
/// Default value is <b>true</b>, all metafiles are compressed regardless of its size.
/// </summary>
public bool AlwaysCompressMetafiles

UseCase:

Document doc = new Document(@"sourse.doc");
DocSaveOptions saveOptions = new DocSaveOptions();
saveOptions.AlwaysCompressMetafiles = false;
doc.Save("SmallMetafilesUncompressed.doc", saveOptions);

License.IsLicensed marked as obsolete

This property will be removed later by security reason.

/// <summary>
/// Returns true if a valid license has been applied; false if the component is running in evaluation mode.
/// </summary>
[Obsolete("This property is obsolete. SetLicense() method raises an exception if license is invalid.")]
public bool IsLicensed

WORDSNET-3714 Ability to read macros from the document

Implemented feature to get access to VBA project source code. Following classes have been added: VbaProject, VbaModuleCollection, VbaModule.

/// <summary>
/// Provides access to VBA project information.
/// A VBA project inside the document is defined as a collection of VBA modules.
/// </summary>
public class VbaProject
{
    /// <summary>
    /// Returns VBA project name.
    /// </summary>
    public string Name
    {
        get;
    }
    /// <summary>
    /// Returns collection of VBA project modules.
    /// </summary>
    public VbaModuleCollection Modules
    {
        get;
    }
}
/// <summary>
/// Provides access to VBA project module.
/// </summary>
public class VbaModule
{
    /// <summary>
    /// Returns VBA project module name.
    /// </summary>
    public string Name
    {
        get;
    }
    /// <summary>
    /// Returns VBA project module source code.
    /// </summary>
    public string SourceCode
    {
        get;
    }
}

UseCase:

Document doc = new Document(filename);
if(doc.VbaModule != null)
    foreach(VbaModule module in doc.VbaProject.Modules)
        Console.WriteLine(module.SourceCode);

WORDSNET-17856 Obsolete method Replace() was removed from the Range class

Obsolete method Replace was removed from Range class. And fixed a few minor bugs in new FindReplacer. Pay attention that new FindReplacer behavior may differ for some cases(e.g. SmartTag replacement). Currently available next Replace methods:

/// <summary>
/// Replaces all occurrences of a character pattern specified by a regular expression with another string.
/// </summary>
/// <remarks>
/// <p>Replaces the whole match captured by the regular expression.</p>
/// <p>Method is able to process breaks in both pattern and replacement strings.</p>
/// You should use special meta-characters if you need to work with breaks:
/// <list type="bullet">
/// <item><b>&p</b> - paragraph break</item>
/// <item><b>&b</b> - section break</item>
/// <item><b>&m</b> - page break</item>
/// <item><b>&l</b> - manual line break</item>
/// </list>
/// To leave any meta-character intact a parameter <see cref="FindReplaceOptions.PreserveMetaCharacters"/> should be set to true.
/// </remarks>
/// <param name="pattern">A regular expression pattern used to find matches.</param>
/// <param name="replacement">A string to replace all occurrences of pattern.</param>
/// <param name="options"><see cref="FindReplaceOptions"/> object to specify additional options.</param>
/// <returns>The number of replacements made.</returns>
public int Replace(string pattern, string replacement)
public int Replace(string pattern, string replacement, FindReplaceOptions options)
public int Replace(Regex pattern, string replacement)
public int Replace(Regex pattern, string replacement, FindReplaceOptions options)

WORDSNET-18400 - Implemented table style public API

New public properties have been added into the TableStyle class, and the new public types ConditionalStyleCollection, ConditionalStyle, ConditionalStyleType have been implemented.

public class TableStyle : Style
{
    // Gets or sets a flag indicating whether text in a table row is allowed to split across a page break.
    // The default value is true.
    public bool AllowBreakAcrossPages
    {
        get; set;
    }

    // Gets the collection of default cell borders for the style.
    public BorderCollection Borders
    {
        get;
    }

    // Gets or sets the amount of space (in points) to add to the left of the contents of table cells.
    public double LeftPadding
    {
        get; set;
    }

    // Gets or sets the amount of space (in points) to add to the right of the contents of table cells.
    public double RightPadding
    {
        get; set;
    }

    // Gets or sets the amount of space (in points) to add above the contents of table cells.
    public double TopPadding
    {
        get; set;
    }

    // Gets or sets the amount of space (in points) to add below the contents of table cells.
    public double BottomPadding
    {
        get; set;
    }

    // Specifies the alignment for the table style.
    // The default value is TableAlignment.Left.
    public TableAlignment Alignment
    {
        get; set;
    }

    // Gets or sets the amount of space (in points) between the cells.
    public double CellSpacing
    {
        get; set;
    }

    // Gets or sets whether this is a style for a right-to-left table.
    // When true, the cells in rows are laid out right to left.
    // The default value is false.
    public bool Bidi
    {
        get; set;
    }

    // Gets or sets the value that represents the left indent of a table.
    public double LeftIndent
    {
        get: set;
    }

    // Gets a Shading object that refers to the shading formatting for table cells.
    public Shading Shading
    {
        get;
    }

    // Gets or sets a number of rows to include in the banding when the style specifies odd/even row banding.
    public int RowStripe
    {
        get; set;
    }

    // Gets or sets a number of columns to include in the banding when the style specifies odd/even columns banding.
    public int ColumnStripe
    {
        get; set;
    }

    // Collection of conditional styles that may be defined for this table style.
    public ConditionalStyleCollection ConditionalStyles
    {
        get;
    }
}

// Represents a collection of ConditionalStyle objects.

// It is not possible to add or remove items from this collection. It contains permanent set of items: one item for

// each value of the ConditionalStyleType enumeration type.
public class ConditionalStyleCollection : IEnumerable<ConditionalStyle>
{
    // Clears all conditional styles of the table style.
    public void ClearFormatting();

    // Retrieves a ConditionalStyle object by conditional style type.
    public ConditionalStyle this[ConditionalStyleType conditionalStyleType]
    {
        get;
    }

    // Retrieves a ConditionalStyle object by index.
    // index: Zero-based index of the conditional style to retrieve.
    public ConditionalStyle this[int index]
    {
        get;
    }

    // Gets the number of conditional styles in the collection.
    public int Count
    {
        get;
    }

    // Gets the first row style.
    public ConditionalStyle FirstRow
    {
        get;
    }

    // Gets the first column style.
    public ConditionalStyle FirstColumn
    {
        get;
    }

    // Gets the last row style.
    public ConditionalStyle LastRow
    {
        get;
    }

    // Gets the last column style.
    public ConditionalStyle LastColumn
    {
        get;
    }

    // Gets the odd row banding style.
    public ConditionalStyle OddRowBanding
    {
        get;
    }

    // Gets the odd column banding style.
    public ConditionalStyle OddColumnBanding
    {
        get;
    }

    // Gets the even row banding style.
    public ConditionalStyle EvenRowBanding
    {
        get;
    }

    // Gets the even column banding style.
    public ConditionalStyle EvenColumnBanding
    {
        get;
    }

    // Gets the top left cell style.
    public ConditionalStyle TopLeftCell
    {
        get;
    }

    // Gets the top right cell style.
    public ConditionalStyle TopRightCell
    {
        get;
    }

    // Gets the bottom left cell style.
    public ConditionalStyle BottomLeftCell
    {
        get;
    }

    // Gets the bottom right cell style.
    public ConditionalStyle BottomRightCell
    {
        get;
    }
 }

// Represents special formatting applied to some area of a table with assigned table style.
public class ConditionalStyle
{
    // Clears formatting of this conditional style.
    public void ClearFormatting();

    // Gets the paragraph formatting of the conditional style.
    public ParagraphFormat ParagraphFormat
    {
        get:
    }

    // Gets the character formatting of the conditional style.
    public Font Font
    {
        get;
    }

    // Gets a Shading object that refers to the shading formatting for this conditional style.
    public Shading Shading
    {
        get;
    }

    // Gets the collection of default cell borders for the conditional style.
    public BorderCollection Borders
    {
        get;
    }

    // Gets or sets the amount of space (in points) to add to the left of the contents of table cells.
    public double LeftPadding
    {
        get; set;
    }

    // Gets or sets the amount of space (in points) to add to the right of the contents of table cells.
    public double RightPadding
    {
        get; set;
    }

    // Gets or sets the amount of space (in points) to add above the contents of table cells.
    public double TopPadding
    {
        get; set;
    }

    // Gets or sets the amount of space (in points) to add below the contents of table cells.
    public double BottomPadding
    {
        get; set;
    }

    // Gets table area to which this conditional style relates.
    public ConditionalStyleType Type
    {
        get;
    }
 }

// Represents possible table areas to which conditional formatting may be defined in a table style.
public enum ConditionalStyleType
{
    // Specifies formatting of the first row of a table.
    FirstRow,

    // Specifies formatting of the first column of a table.
    FirstColumn,

    // Specifies formatting of the last row of a table.
    LastRow,

    // Specifies formatting of the last column of a table.
    LastColumn,

    // Specifies formatting of odd-numbered row stripe.
    OddRowBanding,

    // Specifies formatting of odd-numbered column stripe.
    OddColumnBanding,

    // Specifies formatting of even-numbered row stripe.
    EvenRowBanding,

    // Specifies formatting of even-numbered column stripe.
    EvenColumnBanding,

    // Specifies formatting of the top left cell of a table.
    TopLeftCell,

    // Specifies formatting of the top right cell of a table.
    TopRightCell,

    // Specifies formatting of the bottom left cell of a table.
    BottomLeftCell,

    // Specifies formatting of the bottom right cell of a table.
    BottomRightCell
}

The StyleCollection.Add method allows the creation of table styles now.

UseCase to create a table style:

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Table table = builder.StartTable();
builder.InsertCell();
builder.Write("Name");
builder.InsertCell();
builder.Write("Value");
builder.EndRow();
builder.InsertCell();
builder.InsertCell();
builder.EndTable();
TableStyle tableStyle = (TableStyle)doc.Styles.Add(StyleType.Table, "MyTableStyle1");
tableStyle.Borders.LineStyle = LineStyle.Double;
tableStyle.Borders.LineWidth = 1;
tableStyle.LeftPadding = 18;
tableStyle.RightPadding = 18;
tableStyle.TopPadding = 12;
tableStyle.BottomPadding = 12;
table.Style = tableStyle;
doc.Save(dir + "TableStyleCreation.docx");

UseCase to define conditional formatting (special formatting of header row)

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Table table = builder.StartTable();
builder.InsertCell();
builder.Write("Name");
builder.InsertCell();
builder.Write("Value");
builder.EndRow();
builder.InsertCell();
builder.InsertCell();
builder.EndTable();
TableStyle tableStyle = (TableStyle)doc.Styles.Add(StyleType.Table, "MyTableStyle1");

// Define background color to the first row of table.
tableStyle.ConditionalStyles.FirstRow.Shading.BackgroundPatternColor = Color.GreenYellow;
tableStyle.ConditionalStyles.FirstRow.Shading.Texture = TextureIndex.TextureNone;
table.Style = tableStyle;
doc.Save(dir + "TableConditionalStyle.docx");

WORDSNET-18570 Added public method ConvertToHorizontallyMergedCells

There are two well-known techniques used by MS Word to implement horizontally merged cells inside the table. The first one is the merge flags, like Cell.CellFormat.HorizontalMerge, but according to the latest MS Word behavior looks like this way is not used anymore and MS Word just does not write merge flags. Instead, MS Word uses another technique, where cells are merged horizontally by its width.

So, when cells are horizontally merged by its width – there are no merge flags and of course, there is no way to use merge flags to detect which cells are merged. Some customers found this inconvenient.

To resolve this inconvenience, we have added a new public method to convert cells which are horizontally merged by its width to the cell horizontally merged by flags.

Note. Method transforms table and adds new cells when needed.

UseCase:

Document doc = new Document(filename);
Table table = doc.FirstSection.Body.Tables[0];
table.ConvertToHorizontallyMergedCells();
   // Now merged cells have appropriate merge flags.