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);
}
}
目前无法在 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);
}
}