Search code examples
c#itext

ITextSharp New lines in Dictionary


Currently stuck producing Piece Info (despite the deprecation) onto PDFs, and I'm having an issue meeting the requirement due to how itextsharp is spitting out the dictionary into the PDF.

Basically I'm just doing

dictionary.Put(Field1, new PdfString("Value1"));
dictionary.Put(Field2, new PdfString("Value2"));
dictionary.Put(Field3, new PdfString("Value3"));
dictionary.Put(Field4, new PdfString("Value4"));

which results in this in the PDF:

/Field1(Value1)/Field2(Value2)/Field3(Value3)/Field4(Value4)

This should be absolutely fine...but since the parser of the people I am producing this for reads each line individually...I need to produce it so that it outputs into the PDF like so:

/Field1(Value1)
/Field2(Value2)
/Field3(Value3)
/Field4(Value4)

Anyone know of a way to get iTextSharp dictionaries to toss a new line between each entry?


Solution

  • You could create your ownn PdfDictionary implementation and override ToPdf(...) and use this instead of the original

    public class MyPdfDictionary : PdfDictionary
    {
      public override void ToPdf (PdfWriter writer, Stream os)
      {
        // Do it your way
      }
    }
    

    Here you can find the original implementation PdfDictionary

    EDIT: now I tried it myself and works as intended. I only added one line, the rest is a copy of the code from the link above:

      public class CustomPdfDictionary : PdfDictionary
      {
        public override void ToPdf (PdfWriter writer, Stream os)
        {
          PdfWriter.CheckPdfIsoConformance (writer, PdfIsoKeys.PDFISOKEY_OBJECT, this);
          os.WriteByte ((byte)'<');
          os.WriteByte ((byte)'<');
    
          // loop over all the object-pairs in the Hashtable
          PdfObject value;
          foreach (KeyValuePair<PdfName, PdfObject> e in hashMap)
          {
            value = e.Value;
            e.Key.ToPdf (writer, os);
            int type = value.Type;
            if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING)
              os.WriteByte ((byte)' ');
            value.ToPdf (writer, os);
            // Customization start
            os.Write (new byte[] { 13, 10 }, 0, 2);
            // Customization end
          }
          os.WriteByte ((byte)'>');
          os.WriteByte ((byte)'>');
        }
      }
    

    And here is the code using it:

      using (var document = new Document (PageSize.A4))
      using (var outputStream = new FileStream ("D:\\Temp\\result.pdf", FileMode.Create))
      using (var pdfWriter = PdfWriter.GetInstance (document, outputStream))
      {
        document.Open ();
        var dictionary = new CustomPdfDictionary ();
        dictionary.Put (new PdfName ("Field1"), new PdfString ("Value1"));
        dictionary.Put (new PdfName ("Field2"), new PdfString ("Value2"));
        dictionary.Put (new PdfName ("Field3"), new PdfString ("Value3"));
        dictionary.Put (new PdfName ("Field4"), new PdfString ("Value4"));
        dictionary.Put (new PdfName ("Field5"), new PdfString ("Value5"));
        pdfWriter.AddToBody (dictionary);
    
        document.Add (new Paragraph ("Hello World!"));
    
        document.Close ();
      }
    

    and the resulting PDF looks like predicted as you can see in stream 1 0 obj

    %PDF-1.4
    %âãÏÓ
    1 0 obj
    <</Field1(Value1)
    /Field2(Value2)
    /Field3(Value3)
    /Field4(Value4)
    /Field5(Value5)
    >>
    endobj
    3 0 obj
    <</Length 65/Filter/FlateDecode>>stream
    xœ+är
    á22U°04WIá2PÐ5´ 1ôÝBÒ¸4<RsròÂó‹rR5C²€j@*\C¸¹ Çi°
    endstream
    endobj
    5 0 obj
    <</Type/Page/MediaBox[0 0 595 842]/Resources<</Font<</F1 2 0 R>>>>/Contents 3 0 R/Parent 4 0 R>>
    endobj
    2 0 obj
    <</Type/Font/Subtype/Type1/BaseFont/Helvetica/Encoding/WinAnsiEncoding>>
    endobj
    4 0 obj
    <</Type/Pages/Count 1/Kids[5 0 R]>>
    endobj
    6 0 obj
    <</Type/Catalog/Pages 4 0 R>>
    endobj
    7 0 obj
    <</Producer(iTextSharp’ 5.5.13.3 ©2000-2022 iText Group NV \(AGPL-version\))/CreationDate(D:20220414220947+02'00')/ModDate(D:20220414220947+02'00')>>
    endobj
    xref
    0 8
    0000000000 65535 f 
    0000000015 00000 n 
    0000000363 00000 n 
    0000000120 00000 n 
    0000000451 00000 n 
    0000000251 00000 n 
    0000000502 00000 n 
    0000000547 00000 n 
    trailer
    <</Size 8/Root 6 0 R/Info 7 0 R/ID [<d852ba3dcf1f78129453dbef9be1a4e5><d852ba3dcf1f78129453dbef9be1a4e5>]>>
    %iText-5.5.13.3
    startxref
    712
    %%EOF
    

    PS: I'm not sure if this now violates ISO-32000 but it's the result you wanted