Image in table not centered when converting word to pdf

I’m generating a word document using DocumentBuilder, which I will then save as a pdf. The word document is made properly, but when converting to pdf, I have an image centered in a table which is no longer centered.
Table in word:
image.jpg (107.1 KB)

Rendered PDF:
image.jpg (43.0 KB)

I am saving to pdf by running the following:
builder.Document.Save(docStream, Aspose.Words.Saving.SaveOptions.CreateSaveOptions(SaveFormat.Pdf));

This is a .Net Core application.

To replicate, create a document, then:

var table = builder.StartTable();
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = (builder.PageSetup.PageWidth * 4) / 12;
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = (builder.PageSetup.PageWidth * 4) / 12;
var shape = builder.InsertImage("path/to/image");
var imageSize = shape.ImageData.ImageSize;
var scale = builder.CellFormat.Width / imageSize.WidthPoints;
shape.Width = builder.CellFormat.Width;
shape.Height = imageSize.HeightPoints * scale;
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = (builder.PageSetup.PageWidth * 4) / 12;
builder.EndRow();
table.StyleOptions = TableStyleOptions.None;
table.ClearBorders();
table.TopPadding = table.BottomPadding = table.RightPadding = table.LeftPadding = 0;
builder.EndTable();
builder.Document.Save(@"somepath/test.docx");
builder.Document.Save(@"somepath/test.pdf", SaveFormat.Pdf);

Please note this is chopped out of my code, so may not compile as is without minor changes.

@bkane521,

Thanks for your inquiry. We tested the scenario and have managed to reproduce the same problem on our end. For the sake of correction, we have logged this problem in our issue tracking system. The ID of this issue is WORDSNET-19131. We will further look into the details of this problem and will keep you updated on the status of correction. We apologize for your inconvenience.

@bkane521,

In the meantime while you are waiting for a fix, as a workaround, you may use the Document.UpdateTableLayout method before saving to PDF. Please check the following code. Hope, this helps:

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

var table = builder.StartTable();
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = (builder.PageSetup.PageWidth * 4) / 12;
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = (builder.PageSetup.PageWidth * 4) / 12;
var shape = builder.InsertImage("E:\\Temp\\Aspose.Words.jpg");
var imageSize = shape.ImageData.ImageSize;
var scale = builder.CellFormat.Width / imageSize.WidthPoints;
shape.Width = builder.CellFormat.Width;
shape.Height = imageSize.HeightPoints * scale;
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = (builder.PageSetup.PageWidth * 4) / 12;
builder.EndRow();
table.StyleOptions = TableStyleOptions.None;
table.ClearBorders();
table.TopPadding = table.BottomPadding = table.RightPadding = table.LeftPadding = 0;
builder.EndTable();            

doc.Save("E:\\Temp\\output.docx");

doc.UpdateTableLayout();
doc.Save("E:\\Temp\\output.pdf");

Thank you, this does appear to fix the problem, but when I have other cells in the table where I am setting the text alignment differently (left and centered) the image once again appears off center, and the size of the table seems to change. Is there any relation with these problems, or a simple way to work around this as well?

I appreciate the support.

Upon further testing, it doesn’t seem to be related to text alignment or text styling; simply having another row (or perhaps cell) throws off the table’s sizing/alignment. See below;
An image alone in a table, as in the previous code I posted:
Screen Shot 2019-09-01 at 4.31.26 PM.png (22.1 KB)

And then the same table with a row added before containing text:
Screen Shot 2019-09-01 at 4.31.41 PM.png (23.2 KB)

@bkane521,

Can you please also provide a simple source code where even Document.UpdateTableLayout method does not produce expected PDF output?

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

var table = builder.StartTable();
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = builder.PageSetup.PageWidth;
builder.Write("test");
builder.EndRow();
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = (builder.PageSetup.PageWidth * 4) / 12;
var shape = builder.InsertImage("E:\\Temp\\Aspose.Words.jpg");
var imageSize = shape.ImageData.ImageSize;
var scale = builder.CellFormat.Width / imageSize.WidthPoints;
shape.Width = builder.CellFormat.Width;
shape.Height = imageSize.HeightPoints * scale;
builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.None;
builder.CellFormat.Width = (builder.PageSetup.PageWidth * 4) / 12;
builder.EndRow();
table.StyleOptions = TableStyleOptions.None;
table.ClearBorders();
table.TopPadding = table.BottomPadding = table.RightPadding = table.LeftPadding = 0;
builder.EndTable();    

This is the same code, but inserting a row in the table before the row containing the image. This should replicate the issue.

@bkane521,

I have generated a DOCX file and a PDF file by using the code you provided. But, can you please also ZIP and attach your expected document showing the correct output here for testing. You can create expected document by using MS Word. We will then investigate the scenario on our end and provide you more information.

Attachment: Docs.zip (36.1 KB)

Hello,
The document I would expect from the code provided would look something like the following: Document.zip (30.8 KB)

I would expect the first row (one cell) to take the entire width of the document, then in the second row I am creating three cells each set to be 1/3rd the width of the page, with the image in the center. It seems that when there is already a row in the table, adding cells and setting their widths doesn’t quite work as I expected, and also seems to modify the already existing row.

For our use case, we are allowing users to set up dynamically how they would like documents to be generated (e.g. letting them choose the width and offset of certain elements as a percentage of the page width) in a web UI, then we want to use Aspose to generate a docx and pdf for them to download. However it seems that building a table with specific cell widths may not be the correct approach - I don’t know if this is expected behavior for Aspose or not.

@bkane521,

You can get the desired output by using the following code:

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

PageSetup ps = doc.FirstSection.PageSetup;
double pageWidth =  ps.PageWidth - ps.LeftMargin - ps.RightMargin;

Table table = builder.StartTable();
builder.InsertCell();
builder.CellFormat.Width = pageWidth / 3;
builder.CellFormat.HorizontalMerge = CellMerge.First;
builder.Write("Test – this cell is the width of the page, and the image is centered in the next row");

builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.Previous;

builder.InsertCell();
builder.CellFormat.HorizontalMerge = CellMerge.Previous;
builder.EndRow();

builder.InsertCell();
builder.CellFormat.ClearFormatting();
builder.CellFormat.Width = pageWidth / 3;

builder.InsertCell();
builder.CellFormat.Width = pageWidth / 3;
var shape = builder.InsertImage(@"E:\Temp\Aspose.Words.jpg");
var imageSize = shape.ImageData.ImageSize;
var scale = builder.CellFormat.Width / imageSize.WidthPoints;
shape.Width = builder.CellFormat.Width;
shape.Height = imageSize.HeightPoints * scale;

builder.InsertCell();
builder.CellFormat.Width = pageWidth / 3;
builder.EndRow();

table.StyleOptions = TableStyleOptions.None;
table.ClearBorders();
table.TopPadding = table.BottomPadding = table.RightPadding = table.LeftPadding = 0;

builder.EndTable();

table.AutoFit(AutoFitBehavior.FixedColumnWidths);

doc.Save("E:\\Temp\\19.8.docx");
doc.Save("E:\\Temp\\19.8.pdf");

Thanks for your reply - so rows should always contain the same number of cells, and if I merge the cells accordingly I can size them arbitrarily?

@bkane521,

No, it is not required that all rows should have same number of cells. For example, the following code will insert one cell in first row and three cells in second row.

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

PageSetup ps = doc.FirstSection.PageSetup;
double pageWidth = ps.PageWidth - ps.LeftMargin - ps.RightMargin;

Table table = builder.StartTable();
builder.InsertCell();
builder.CellFormat.Width = pageWidth;
builder.Write("Test – this cell is the width of the page, and the image is centered in the next row");
builder.EndRow();

builder.InsertCell();
builder.CellFormat.ClearFormatting();
builder.CellFormat.Width = pageWidth / 3;

builder.InsertCell();
builder.CellFormat.Width = pageWidth / 3;
var shape = builder.InsertImage(@"E:\Temp\Aspose.Words.jpg");
var imageSize = shape.ImageData.ImageSize;
var scale = builder.CellFormat.Width / imageSize.WidthPoints;
shape.Width = builder.CellFormat.Width;
shape.Height = imageSize.HeightPoints * scale;

builder.InsertCell();
builder.CellFormat.Width = pageWidth / 3;
builder.EndRow();

table.StyleOptions = TableStyleOptions.None;
table.ClearBorders();
table.TopPadding = table.BottomPadding = table.RightPadding = table.LeftPadding = 0;

builder.EndTable();

table.AutoFit(AutoFitBehavior.FixedColumnWidths);

doc.Save("E:\\Temp\\19.8.docx");
doc.Save("E:\\Temp\\19.8.pdf");

It looks like this solved my problem, thank you very much

@bkane521,

Thanks for your feedback. In case you have further inquiries or need any help in future, please let us know.

Regarding WORDSNET-19131, we will keep you posted on any further updates.

@bkane521,

Regarding WORDSNET-19131, it is to update you that the issue occurs because missing table grid is currently not calculated correctly by Aspose.Words for a generated auto-fit table with a DML shape inside. The problematic shape is in a table column and the position is not correct because table column widths are not correct.

Column widths calculation for tables is addressed by the new table grid calculation algorithm being implemented per another issue ID WORDSNET-832. Currently, the algorithm skips auto-fit tables with inline DML shapes because there were problems with shape metrics in some other test documents.

We are postponing WORDSNET-19131 until inline DML shape metrics are supported. You may set AutoFit to false for the generated table as a workaround.

Rest assured, we will inform you via this thread as soon as this issue will be resolved in future. We apologize for any inconvenience.

The issues you have found earlier (filed as WORDSNET-19131) have been fixed in this Aspose.Words for .NET 23.7 update also available on NuGet.