0

I'm using IText 7 in dotnet core to manipulate a PDF file.

Once the process has completed I'm finding myself with a 5-page PDF at 14.2MB.

When I open the generated PDF in Adobe Reader I am prompted to save when closing Reader. If i choose Yes it shrinks the pdf by 50%.

Here is the pertinent code:

// ASDLine Model
public class ASDLine
{
    public long ARInvoiceHeaderKey { get; set; }
    public string BillingCode { get; set; }
    public string Description { get; set; }
    public decimal Amount { get; set; }
    public bool? MatchProfile { get; set; }
}


public AuditSummaryDocument Create()
{
    // Load in the template
    MemoryStream outputDoc = new MemoryStream();

    // Attempt to shrink the PDF..(didn't make any difference)
    var w = new PdfWriter(outputDoc);
    var wb = w.IsFullCompression();
    w.SetCompressionLevel(9);
    w.SetSmartMode(true);

    PdfDocument pdfDoc = new PdfDocument(new PdfReader("mytemplate.pdf"), w);

    font = PdfFontFactory.CreateRegisteredFont("Calibri");
    Document doc = new Document(pdfDoc);

    PdfAcroForm pdfAcroForm = PdfAcroForm.GetAcroForm(pdfDoc, true);
    var fields = pdfAcroForm.GetFormFields();

    //header:
    fields["generated"].SetValue($"{DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}");            
    // .... lots of fields

    pdfAcroForm.FlattenFields();

    // Add lines
    Table table = GenerateTable();

    table.SetRelativePosition(0, 510, 0, 0);
    doc.Add(table);

    // attempt to shrink PDF
    pdfDoc.SetFlushUnusedObjects(true);

    pdfDoc.Close();


    //outputDoc.Position = 0;
    var r = new AuditSummaryDocument
    {
        Data = outputDoc.ToArray()
    };

    return r;
}

The table looks like this:

private Table GenerateTable()
{
    // Example list of ASDLine
    var list = new List<ASDLine>();
    list.Add(new ASDLine { Amount = 20, ARInvoiceHeaderKey = 1, BillingCode = "ABC123", Description = "A billing code 1", MatchProfile = null });
    list.Add(new ASDLine { Amount = 40, ARInvoiceHeaderKey = 1, BillingCode = "ABC456", Description = "A billing code 2", MatchProfile = true });
    list.Add(new ASDLine { Amount = 60, ARInvoiceHeaderKey = 1, BillingCode = "ABC789", Description = "A billing code 3", MatchProfile = false });
    list.Add(new ASDLine { Amount = 80, ARInvoiceHeaderKey = 1, BillingCode = "ABC987", Description = "A billing code 4", MatchProfile = true });

    Table table = new Table(new UnitValue[] { new UnitValue(UnitValue.POINT, 80)
                                             ,new UnitValue(UnitValue.POINT, 370)
                                             ,new UnitValue(UnitValue.POINT, 80)
                                             ,new UnitValue(UnitValue.POINT, 80)});
    table.SetWidth(new UnitValue(UnitValue.PERCENT, 102));

    Style hs = new Style();
    hs.SetFont(font);
    hs.SetFontSize(10);
    hs.SetBold();
    hs.SetTextAlignment(TextAlignment.CENTER);

    Style cs = new Style();
    cs.SetFont(font);
    cs.SetFontSize(10);

    table.AddHeaderCell(new Cell().AddStyle(hs).Add(new Paragraph("Billing Code")));
    table.AddHeaderCell(new Cell().AddStyle(hs).Add(new Paragraph("Description")));
    table.AddHeaderCell(new Cell().AddStyle(hs).Add(new Paragraph("Amount")));
    table.AddHeaderCell(new Cell().AddStyle(hs).Add(new Paragraph("Match Profile")));

    list.ForEach(line =>
    {
        table.AddCell(new Cell().AddStyle(cs).SetTextAlignment(TextAlignment.CENTER).Add(new Paragraph(line.BillingCode)));
        table.AddCell(new Cell().AddStyle(cs).SetTextAlignment(TextAlignment.LEFT).Add(new Paragraph(line.Description)));
        table.AddCell(new Cell().AddStyle(cs).SetTextAlignment(TextAlignment.RIGHT).Add(new Paragraph(line.Amount.ToString("C"))));
        table.AddCell(new Cell().AddStyle(cs).SetTextAlignment(TextAlignment.CENTER).Add(new Paragraph(line.MatchProfile.HasValue ? line.MatchProfile.Value ? "Yes" : "No" : "-")));
    });

    return table;
}

What am I doing wrong with my code that results in this PDF being twice the size it should be - and why does Adobe prompt to save changes?

Alexey Subach
  • 11,903
  • 7
  • 34
  • 60
Darren Wainwright
  • 30,247
  • 21
  • 76
  • 127
  • 1
    Hi, your code is very hard to reproduce because it contains a lot of undefined things: `ASDHeader`, `ASDLine`, `TEMPLATE_SRC` to the very least. Please create a small, reproducible code sample that does not rely on your project-specific declarations – Alexey Subach May 24 '20 at 21:20
  • Made a small tweak to help, thanks @AlexeySubach – Darren Wainwright May 25 '20 at 14:09
  • 1
    Still, do run your code I need to create some dummy `ASDLine` instances. Is it possible to simplify the code so that it's easily runnable? I would expect to copy-paste the code and just be able to run it – Alexey Subach May 25 '20 at 15:02
  • @AlexeySubach - I added a sample list. Should be all this needs to run. thanks :) – Darren Wainwright May 25 '20 at 15:09
  • 1
    Well, even when I fixed a small bug (`list.ForEach` instead of `lines.ForEach`), I still need `mytemplate.pdf` file to really run the code. – Alexey Subach May 25 '20 at 21:33
  • I'm sorry, I can't share that - confidential information on it. I've tried a couple of PDF's and its the same issue - I presume I'm doing something wrong in code. Thanks for trying though @AlexeySubach. – Darren Wainwright May 26 '20 at 13:21

0 Answers0