Hello,
I am trying to implement a solution that builds PDF documents based on an existing PDF document template. The template is a W2 tax form, which I am programmatically populating with employee information from a database and then creating a single PDF with each populated form appended to the new PDF document. The problem is the created PDF document file size gets quite large. I want to compress the PDF document, as I know there is a lot of duplication that can be eliminated. When I open one of the PDFs that was created by this app, it is originally 700+ MB. After I run "Reduce PDF size" in Acrobat, it goes down to 4 MB.
The Syncfusion package that makes the most sense to use in this app is Pdf.Net.Core, since I am writing a Console app targeting .Net core. The problem with this package is it does not support PDF file compression (at least I haven't found a way to do it and your documentation says "PDF supports compressing PDF document only in Windows Forms, WPF, ASP.NET and ASP.NET MVC platforms."
When I try to use Pdf.Wpf or Pdf.WinForms, I run into a licensing problem "Error: Could not load file or assembly 'Syncfusion.Licensing, Version=20.4460.0.42, Culture=neutral, PublicKeyToken=632609b4d040f6b4'. The system cannot find the file specified." I do not have this problem with the Pdf.Net.Core package.
I did some research and the only suggestion I can find is to add the Syncfusion.Licensing package, but this has not helped the situation.
Please advise on what can be done to resolve this situation.
Thank you,
Vincent
The reported exception might be due to a mismatched product version of Syncfusion assemblies. So, we request you refer to the same product version of Syncfusion assemblies to resolve this issue. Please refer to the below link,
KB: https://www.syncfusion.com/kb/4661/how-to-resolve-could-not-load-file-or-assembly-error
Note: If adding multiple Syncfusion assemblies to your project, it is dependent assemblies must be of the same assembly version, if they are different then the error will occur.
We have attached the video for your reference.
Please follow the below steps if you are using NuGet packages at your side.
Hello and thanks for getting back to me.
Unfortunately, I am still getting the same error after following the steps you provided.
The only step I did not do was to " Ensure the path of the assemblies is referred to properly or not." as I am not sure where to find this. Below is my csproj file for the project that is failing:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DataAccessLibrary\DataAccessLibrary.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Syncfusion.Licensing" Version="20.4.0.43" />
<PackageReference Include="Syncfusion.Pdf.WinForms" Version="20.4.0.43" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
</ItemGroup>
</Project>
Edit:
This is the error message I'm receiving:
Error: Could not load file or assembly 'Syncfusion.Licensing, Version=20.4460.0.43, Culture=neutral, PublicKeyToken=632609b4d040f6b4'. The system cannot find the file specified.
I'm not sure if this is what you mean, but I did confirm that the path to the nuget package looks correct when I examine the Path property of the package:
I don't know what else to try at this point. Please advise.
Thank you,
Vincent
After reviewing the information given, it appears that the problem may be caused by an improper restoration of the Winforms package to the project. Additionally, attempting to install the Winforms package in a Net core application will result in an error. This is because the Winforms package is only compatible with the .net framework, and we recommend using the Syncfusion.Pdf.Net.Core package instead of a Net core platform.
NuGet link - https://www.nuget.org/packages/Syncfusion.Pdf.Net.Core/20.4.0.43
Refer to the screenshot below:
We suggest uninstalling the current package completely and removing the package folder located in the .nuget folder (C:\Users{User Name}.nuget\packages). Try this on your end and let us know the result.
This was my initial approach, from my original post:
The Syncfusion package that makes the most sense to use in this app is Pdf.Net.Core, since I am writing a Console app targeting .Net core. The problem with this package is it does not support PDF file compression (at least I haven't found a way to do it and your documentation says "PDF supports compressing PDF document only in Windows Forms, WPF, ASP.NET and ASP.NET MVC platforms."
So, this brings me back to my original conundrum - Pdf.Net.Core does not support PDF file compression and the PDF files that are being created are much to large. An example of this
is a PDF created via my app is originally 700+ MB. After I run "Reduce PDF size" in Acrobat, it goes down to 4 MB.
Why is compression not available in Pdf.Net.Core? Any suggestions on how I can keep the size of these files down? I'm creating batches of 300 forms per PDF file (that's what the chunkSize and chunkIndex are for). I will provide my code below:
public void FillW2Forms(List<PW2DataModel> data, string documentType, string taxYear, string pdfTemplate, int chunkIndex, int chunkSize)
{
int rowCount = data.Count;
int rangeEnd;
if (rowCount != chunkSize)
{
rangeEnd = ((chunkSize * chunkIndex) - (chunkSize - rowCount));
}
else
{
rangeEnd = (chunkSize * chunkIndex);
}
int rangeStart = ((chunkSize * chunkIndex) - (chunkSize - 1));
int count = 0;
string path = _configuration.GetSection("FormFillValues")["tax_forms_pdf_location"];
//Creates a new PDF document
PdfDocument document = new PdfDocument();
//Set EnableMemoryOptimization to true
document.EnableMemoryOptimization = true;
string fileName = $"{documentType}_{taxYear}_{chunkIndex.ToString("D2")}[{rangeStart}_to_{rangeEnd}].pdf";
//Create output file stream.
using (FileStream outputFileStream = new FileStream(path + fileName, FileMode.Create, FileAccess.ReadWrite))
{
foreach (PW2DataModel row in data)
{
Stream fileIn = new FileStream(pdfTemplate, FileMode.Open, FileAccess.Read, FileShare.Read);
// Create a byte array of file stream length
byte[] pdfData = new byte[fileIn.Length];
//Read block of bytes from stream into the byte array
fileIn.Read(pdfData, 0, Convert.ToInt32(pdfData.Length));
// Load the byte array
PdfLoadedDocument loadedDocument = new PdfLoadedDocument(pdfData);
//Create a new compression option.
//PdfCompressionOptions options = new PdfCompressionOptions();
//options.OptimizeFont = true;
//options.OptimizePageContents = true;
//options.RemoveMetadata = true;
//loadedDocument.CompressionOptions = options;
loadedDocument.Compression = PdfCompressionLevel.Best;
//Get the loaded form
PdfLoadedForm loadedForm = loadedDocument.Form;
(loadedForm.Fields["WSSN"] as PdfLoadedTextBoxField).Text = row.WSSN;
(loadedForm.Fields["WYEAR"] as PdfLoadedTextBoxField).Text = row.WYEAR;
(loadedForm.Fields["WCNTRLNUM"] as PdfLoadedTextBoxField).Text = row.WCNTRLNUM;
(loadedForm.Fields["WEMPIDNUM"] as PdfLoadedTextBoxField).Text = row.WEMPIDNUM;
(loadedForm.Fields["WEMPNAME1"] as PdfLoadedTextBoxField).Text = row.WEMPNAME1;
(loadedForm.Fields["WEMPNAME2"] as PdfLoadedTextBoxField).Text = row.WEMPNAME2;
(loadedForm.Fields["WEADDLN1"] as PdfLoadedTextBoxField).Text = row.WEADDLN1;
(loadedForm.Fields["WEADDLN2"] as PdfLoadedTextBoxField).Text = row.WEADDLN2;
(loadedForm.Fields["WMUSNAME"] as PdfLoadedTextBoxField).Text = row.WMUSNAME;
(loadedForm.Fields["WMADDLN1"] as PdfLoadedTextBoxField).Text = row.WMADDLN1;
(loadedForm.Fields["WMADDLN2"] as PdfLoadedTextBoxField).Text = row.WMADDLN2;
(loadedForm.Fields["WMADDLN3"] as PdfLoadedTextBoxField).Text = row.WMADDLN3;
(loadedForm.Fields["WMADDLN4"] as PdfLoadedTextBoxField).Text = row.WMADDLN4;
(loadedForm.Fields["WMADDLN5"] as PdfLoadedTextBoxField).Text = row.WMADDLN5;
(loadedForm.Fields["WFEDWAGTPS"] as PdfLoadedTextBoxField).Text = row.WFEDWAGTPS;
(loadedForm.Fields["WFEDINCTAX"] as PdfLoadedTextBoxField).Text = row.WFEDINCTAX;
(loadedForm.Fields["WSSWAGES"] as PdfLoadedTextBoxField).Text = row.WSSWAGES;
(loadedForm.Fields["WSSTAX"] as PdfLoadedTextBoxField).Text = row.WSSTAX;
(loadedForm.Fields["WMEDWAGTPS"] as PdfLoadedTextBoxField).Text = row.WMEDWAGTPS;
(loadedForm.Fields["WMEDWAGTAX"] as PdfLoadedTextBoxField).Text = row.WMEDWAGTAX;
(loadedForm.Fields["WSTATE"] as PdfLoadedTextBoxField).Text = row.WSTATE;
(loadedForm.Fields["WSTAIDNUM"] as PdfLoadedTextBoxField).Text = row.WSTAIDNUM;
(loadedForm.Fields["WSTAWAGTPS"] as PdfLoadedTextBoxField).Text = row.WSTAWAGTPS;
(loadedForm.Fields["WSTAWAGTAX"] as PdfLoadedTextBoxField).Text = row.WSTAWAGTAX;
(loadedForm.Fields["WLOCNAMES"] as PdfLoadedTextBoxField).Text = row.WLOCNAMES;
(loadedForm.Fields["WLOCWAGTPS"] as PdfLoadedTextBoxField).Text = row.WLOCWAGTPS;
(loadedForm.Fields["WLOCWAGTAX"] as PdfLoadedTextBoxField).Text = row.WLOCWAGTAX;
(loadedForm.Fields["WOTHER"] as PdfLoadedTextBoxField).Text = row.WOTHER.TrimStart();
//Flatten the whole form.
loadedForm.Flatten = true;
document.Append(loadedDocument);
loadedDocument.Close(true);
count++;
Console.WriteLine($"count: {count}");
// Save the PDF document every 100 pages because when the file gets to large, .Save hangs
if (count % 100 == 0 || count == rowCount)
{
document.Save(outputFileStream);
Console.WriteLine("Saved File!");
}
}
document.Close(true);
}
Console.WriteLine("FINISHED!!!");
}
Thank you,
Vincent
We are currently trying to replicate the reported issue on our end and believe it may be related to the specific document. To help us assist you more accurately, please share the input file you are trying to compress.
Unfortunately, it is not possible to attach PDFs in this forum. Could you upload the file to OneDrive and grant access to our email address, support@syncfusion.com?