ITextSharp 字典中的新行

ITextSharp New lines in Dictionary

目前无法在 PDF 上生成 Piece Info(尽管已弃用),并且由于 itextsharp 如何将字典吐出到 PDF 中,我遇到了满足要求的问题。

基本上我就是在做

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

PDF 中的结果是:

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

这应该是绝对没问题的...但是因为我正在为它制作的人的解析器会单独读取每一行...我需要制作它以便它像这样输出到 PDF 中:

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

有人知道让 iTextSharp 词典在每个条目之间换行的方法吗?

您可以创建自己的 PdfDictionary 实现并覆盖 ToPdf(...) 并使用它代替原来的

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

在这里你可以找到原始实现PdfDictionary

编辑:现在我自己尝试了并且按预期工作。我只添加了一行,其余的是上面link代码的副本:

  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)'>');
    }
  }

下面是使用它的代码:

  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 ();
  }

并且生成的 PDF 看起来像您在流中看到的那样 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:我不确定这现在是否违反了 ISO-32000,但这是您想要的结果

由于您要将 PdfStrings 插入字典,因此请编写 class 覆盖 PdfString 的 ToPdf() 方法而不是覆盖 PdfDictionary。

public class PdfNewLine : PdfString { public PdfNewLine(字符串名称): base(名称) { }

public override void ToPdf(PdfWriter writer, Stream os)
{
    PdfWriter.CheckPdfIsoConformance(writer, PdfIsoKeys.PDFISOKEY_OBJECT, this);
    byte[] bytes = GetBytes();
    ByteBuffer buffer = new ByteBuffer();
    buffer.Append(bytes);
    buffer.Append('\n');
    bytes = StringUtils.EscapeString(buffer.ToByteArray());
    os.Write(bytes, 0, bytes.Length);
}

}