Aspose Cells .NET Core 2.1 saving workbook as PDF fails on Linux box

Hello,

I have a .NET CORE 2.1 app with Aspose cells 18.6.0. It works great on windows machine but fails with following error when saving a workbook as PDF:

Aspose.Cells.CellsException: The type initializer for ‘Gdip’ threw an exception.
at Aspose.Cells.Workbook.Save(String fileName, SaveOptions saveOptions)

This is line its failing on: workbook.Save(localPDFPath, SaveFormat.Pdf);

Details of linux box and .NET Core versions
.NET Core SDK (reflecting any global.json):
Version: 2.1.301
Commit: 59524873d6

Runtime Environment:
OS Name: debian
OS Version: 8
OS Platform: Linux
RID: debian.8-x64
Base Path: /usr/share/dotnet/sdk/2.1.301/

Host (useful for support):
Version: 2.1.1
Commit: 6985b9f684

.NET Core SDKs installed:
2.1.301 [/usr/share/dotnet/sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.1 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.1 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.1 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Please let me know if you need more details.

@rw3

Thanks for using Aspose APIs.

Please do the following steps to resolve your issue.

  1. Install .NetCore SDK
  2. Install libgdiplus
  3. Copy the font files you need and call FontConfigs.SetFontFolder, please see this article i.e. Configuring Fonts for Rendering Spreadsheets

The installation command to install libgdiplus is as follows

sudo apt-get install libgdiplus
ln -s libgdiplus.so gdiplus.dll

Following above steps resolved the issue, thank you! Saving as PDF takes about 10 seconds on linux box vs few 100 milliseconds on the windows box. Is there any optimization need to be implemented for linux version?

@rw3

Thanks for your feedback and using Aspose.Cells API.

We are glad to know that the solution suggested by us was helpful. In case you find any other issue or face some other problem, please feel free to post on our forums, we will be glad to help you further.

Difference in time might be an issue with relevant fonts on your Linux platform, either not installed or specified correctly with its path, please make sure that you have installed all the Microsoft true type fonts (used in the Excel file) on your system and then properly specify the fonts directory path in FontConfigs.SetFontFolder method, see the sample line of code that you should use it at the start of your program before creating Workbook and rendering to PDF.

e.g
Sample code:

FontConfigs.SetFontFolder("/usr/Temp/Fonts" , true);

Please see the document with example code for your reference:

Thank you for prompt response!

Setting FontConfigs.SetFontFolder doesnt seem to help, also PDFs created before and after using FontConfigs.SetFontFolder script has Calibri font in it. Any other thing I can look into?

Also I am getting below warning only for first PDF file generation, not sure if that can shed some light of slowness.
** (process:20744): WARNING **: NOT IMPLEMENTED: GdipWidenPath

** (process:20744): WARNING **: Requested 0 bytes. Maximum size for region is 262144 bytes.

@rw3,

Thank you for providing more details.

You may please try setting the image type as well because we use EMF as default image type which may be causing the above mentioned warnings.

Workbook workbook = new Workbook(filePath);PdfSaveOptions opts = new PdfSaveOptions();
opts.OnePagePerSheet = true;//This line is optional
opts.ImageType = System.Drawing.Imaging.ImageFormat.Png;
workbook.Save(filePath + ".out.pdf", opts);

If still your issue is not resolved, we have to log this issue in our database for which we need the template Excel file and the output PDF files for both Windows and Linux. It will help to analyze the problem.

Seems like opts.ImageType attribute is not available in .NET CORE version. Here is the requested sample and template files. You can also see some pie charts are missing in the linux version.PlanCall.zip (264.7 KB)

@rw3,

It seems that you have sent us different Excel file as it contains 4 charts wherever the alternate PDF files contains more than 12 charts. Please verify that appropriate set of files are shared for our analysis.

Its the same excel file, 2 tabs in excel will be converted into two pages in pdf per category. In the example PDF files I sent there are 6 categories thats why 12 pages, 2 page per category. Hope that make sense.

@rw3,

We were able to understand the issue but we need to look into it more. We have logged the issue in our database for investigation and for a fix. Once, we will have some news for you, we will update you in this topic.

This issue has been logged as

CELLSNET-46223 - Performance degradation for XLSM to PDF conversion in Linux box with .NET Core 2.1

Sounds good, thank you!

@rw3,

You are welcome.

Hello,

Any idea how long it will take to resolve this issue?

@rw3,

We are gathering information for this issue and will provide our feedback soon.

Sounds good, thanks.

@rw3

We have tested the performance on both Windows and Linux.
Here is the test environment:
1, Windows7 64bit, 8GB memory. Test using VS 2017, NUnit3.9.
2, Ubuntu Linux 16.04, 64bit, work on VMware, 2GB memory. test using NUnitLite 3.10.

And, here is the test result:

1, Open the test file and save it, for only one time.
Workbook workbook = new Workbook(Constants.sourcePath + “TMP - Plan Call Page.xlsm”);
workbook.Save(Constants.destPath + “TMP - Plan Call Page.pdf”, SaveFormat.Pdf);
On Windows, it costs about 3.5 seconds.
On Linux, it costs about 7 seconds.

2, Open the test file and save it, for 5 times.
Workbook wb = new Workbook(Constants.TemplatePath + “TMP - Plan Call Page.xlsm”);
wb.Save(Constants.TemplatePath + “PlanCall_out1.pdf”, SaveFormat.Pdf);

        wb = new Workbook(Constants.TemplatePath + "TMP - Plan Call Page.xlsm");
        wb.Save(Constants.TemplatePath + "PlanCall_out2.pdf", SaveFormat.Pdf);

        wb = new Workbook(Constants.TemplatePath + "TMP - Plan Call Page.xlsm");
        wb.Save(Constants.TemplatePath + "PlanCall_out3.pdf", SaveFormat.Pdf);

        wb = new Workbook(Constants.TemplatePath + "TMP - Plan Call Page.xlsm");
        wb.Save(Constants.TemplatePath + "PlanCall_out4.pdf", SaveFormat.Pdf);

        wb = new Workbook(Constants.TemplatePath + "TMP - Plan Call Page.xlsm");
        wb.Save(Constants.TemplatePath + "PlanCall_out5.pdf", SaveFormat.Pdf);

On Windows, it costs about 4.5 seconds.
On Linux, it costs about 9 seconds.

We repeat above tests for several times, and we can confirm the time cost has been correctly recorded.

1, When we run a DLL, it will cost several seconds to do the initialization operation.
The system(Windows or Linux) call a DLL need to do initialization, and our DLL need to initialize some static parameters, and so on.
Based on the system difference, and environment difference(for example, 8GB memory windows, 2GB memory Linux on VMWare), the initialization time may be different.
That is why we open and save the test file for one time, it costs a long time (3.5 seconds on Windows, and 7 seconds on Linux).

2, Then we open and save the test file for 5 times, to see the real “file open and save time” cost.
Based on the time data recorded above, we can approximately get:
The initialization operation cost 3 seconds on Windows, 6 seconds on Linux.
The “file open and save time” is 0.3 second on Windows, 0.6 second on Linux.

So, please check the test again on your environment, run the “open and save” for more than one time, to see the real time cost.
Maybe you ignored the initialization time on Windows, then you get the conclusion: 100ms on Windows, 10 seconds on Linux.
We can see that on Linux(2GB) is slower than on Windows(8GB), for one time, but not for 1000 times.

Thanks for the update, I will check again and get back. Any thoughts on some of the charts getting lost between windows and linux issue?

@rw3,

Check suggested approach on your side and then update us about your findings. Please create separate thread for the problem of missing charts and we will investigate it accordingly.

Hello,

I tried the sample code in our linux box which has 4 GB RAM and it takes ~18 seconds. Comparing that to your stat it seems something else is going on. Is there anything else I can check on?

Here is the code I tried:

     Console.WriteLine("Creating File 1 - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     Workbook wb = new Workbook(_workbookName);
     Console.WriteLine(" Before Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb.Save("plancallPlanCall_out1.pdf", SaveFormat.Pdf);
     Console.WriteLine(" After  Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));

     Console.WriteLine("Creating File 2 - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb = new Workbook(_workbookName);
     Console.WriteLine(" Before Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb.Save("plancallPlanCall_out2.pdf", SaveFormat.Pdf);
     Console.WriteLine(" After  Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));

     Console.WriteLine("Creating File 3 - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb = new Workbook(_workbookName);
     Console.WriteLine(" Before Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb.Save("plancallPlanCall_out3.pdf", SaveFormat.Pdf);
     Console.WriteLine(" After  Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));

     Console.WriteLine("Creating File 4 - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb = new Workbook(_workbookName);
     Console.WriteLine(" Before Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb.Save("plancallPlanCall_out4.pdf", SaveFormat.Pdf);
     Console.WriteLine(" After  Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));

     Console.WriteLine("Creating File 5 - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb = new Workbook(_workbookName);
     Console.WriteLine(" Before Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));
     wb.Save("plancallPlanCall_out5.pdf", SaveFormat.Pdf);
     Console.WriteLine(" After  Save - " + DateTime.Now.ToString("HH:mm:ss.fff"));

Here is the output:

  Creating File 1 - 11:08:21.685
   Before Save - 11:08:24.174
   After  Save - 11:08:29.176
  Creating File 2 - 11:08:29.177
   Before Save - 11:08:29.204
   After  Save - 11:08:31.774
  Creating File 3 - 11:08:31.774
   Before Save - 11:08:31.802
   After  Save - 11:08:34.365
  Creating File 4 - 11:08:34.366
   Before Save - 11:08:34.395
   After  Save - 11:08:36.965
  Creating File 5 - 11:08:36.965
   Before Save - 11:08:36.992
   After  Save - 11:08:39.584

You can see if took ~18 seconds, save operation is most time consuming.

@rw3,

We have investigated your issue further and below are our findings:

After downloading “TMP - Plan Call Page.zip”, it contains 3 files:

  1. TMP - Plan Call Page.xlsm
  2. PC 488214 - Linux.pdf
  3. PC 488214 - Windows.pdf

Then, I tested following codes, on both Windows7 and Ubuntu:

        Workbook workbook = new Workbook(Constants.sourcePath + "TMP - Plan Call Page.xlsm");
        workbook.Save(Constants.destPath + "TMP - Plan Call Page.pdf", SaveFormat.Pdf);

On both Windows7 and Ubuntu, I get the same results:
There are 4 charts in “TMP - Plan Call Page.xlsm” and I can get all the 4 charts in “TMP - Plan Call Page.pdf”.

But I notice that in “TMP - Plan Call Page.zip”:
PC 488214 - Linux.pdf
PC 488214 - Windows.pdf
There are more than 4 charts in them, although they have different chats in them,
but I can not locate the problem based on “TMP - Plan Call Page.xlsm” you provided.

So, would you please check the “TMP - Plan Call Page.xlsm” you have already provided,
Is “PC 488214 - Linux.pdf” and “PC 488214 - Windows.pdf” created by “TMP - Plan Call Page.xlsm”?

Please also provide a “PC 488214.xlsm”, which contains more charts so that we can investigate further and then reply you with all details.