使用 itextsharp 在现有 table/Image 上写入文本
Write text on existing table/Image using itextsharp
已有 table/image。我用pdfcontentbyte写文字的时候,写在这个table/image.
后面
我也想从右边写正文table/column。
我目前用来生成上图的代码:
// open the reader
PdfReader reader = new PdfReader(oldFile);
iTextSharp.text.Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
// open the writer
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.EMBEDDED);
string text = "WV0501";
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(2, text, 155, 655, 0);
cb.EndText();
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
writer.Close();
您没有向我们展示您的代码,因此我们不得不猜测您做错了什么。
内容未显示:
您的代码中可能有这一行:
PdfContentByte canvas = pdfStamper.GetUnderContent(page);
如果是这样,您应该将其替换为以下行:
PdfContentByte canvas = pdfStamper.GetOverContent(page);
向我们展示您的代码后更新:
您想向现有文档添加内容,但您正在使用 Document
和 PdfWriter
的组合。你为什么做这个?请阅读我的书的第 6 章,您将在其中了解 PdfStamper
。
现在,您首先添加文本,然后用现有文档中的页面覆盖它。这意味着现有页面将覆盖文本。
你可以这样切换:
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.EMBEDDED);
string text = "WV0501";
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(2, text, 155, 655, 0);
cb.EndText();
现在文本将覆盖页面,但这并不意味着您的代码更好。你真的应该使用 PdfStamper
而不是 PdfWriter
:
PdfReader reader = new PdfReader(oldFile);
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfStamper stamper = new PdfStamper(reader, fs);
PdfContentByte canvas = stamper.GetOverContent(1);
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
ColumnText.ShowTextAligned(
canvas,
Element.ALIGN_RIGHT,
new Phrase("WV0501", new Font(bf, 9)),
155, 655, 0
);
stamper.Close();
你不同意这样更优雅吗?
重要提示:
在您的代码中您使用:
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.EMBEDDED);
然而,这没有多大意义:COURIER_BOLD
是标准 Type 1 字体之一,因此 embedded
参数被忽略。我将其更改为 NOT_EMBEDDED
因为如果您使用 EMBEDDED
阅读您的代码并且对 PDF 和 iText 一无所知的开发人员可能会感到困惑。他们可能会问:为什么参数说应该嵌入字体却没有嵌入?
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
从右边开始写:
您正在使用数字定义比对:2
。我建议您不要在代码中使用数字,而是使用常量:ALIGN_RIGHT
。这样,我们看到您想要右对齐文本。
文本相对于您定义的坐标右对齐:
x = 155
y = 655
如果您对文本的位置不满意,您应该更改这些硬编码坐标。例如:增加 x
并减少 y
.
您可能希望文本相对于 table 单元格或图像的边框。如果是这种情况,您不应该对坐标进行硬编码。
在 SO 的另一个问题中讨论了检索图像的坐标。检索 table 的坐标很可能是不可能的。这完全取决于原始 PDF 的性质。
已有 table/image。我用pdfcontentbyte写文字的时候,写在这个table/image.
后面我也想从右边写正文table/column。
我目前用来生成上图的代码:
// open the reader
PdfReader reader = new PdfReader(oldFile);
iTextSharp.text.Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
// open the writer
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.EMBEDDED);
string text = "WV0501";
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(2, text, 155, 655, 0);
cb.EndText();
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
writer.Close();
您没有向我们展示您的代码,因此我们不得不猜测您做错了什么。
内容未显示:
您的代码中可能有这一行:
PdfContentByte canvas = pdfStamper.GetUnderContent(page);
如果是这样,您应该将其替换为以下行:
PdfContentByte canvas = pdfStamper.GetOverContent(page);
向我们展示您的代码后更新:
您想向现有文档添加内容,但您正在使用 Document
和 PdfWriter
的组合。你为什么做这个?请阅读我的书的第 6 章,您将在其中了解 PdfStamper
。
现在,您首先添加文本,然后用现有文档中的页面覆盖它。这意味着现有页面将覆盖文本。
你可以这样切换:
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.EMBEDDED);
string text = "WV0501";
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(2, text, 155, 655, 0);
cb.EndText();
现在文本将覆盖页面,但这并不意味着您的代码更好。你真的应该使用 PdfStamper
而不是 PdfWriter
:
PdfReader reader = new PdfReader(oldFile);
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfStamper stamper = new PdfStamper(reader, fs);
PdfContentByte canvas = stamper.GetOverContent(1);
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
ColumnText.ShowTextAligned(
canvas,
Element.ALIGN_RIGHT,
new Phrase("WV0501", new Font(bf, 9)),
155, 655, 0
);
stamper.Close();
你不同意这样更优雅吗?
重要提示:
在您的代码中您使用:
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.EMBEDDED);
然而,这没有多大意义:COURIER_BOLD
是标准 Type 1 字体之一,因此 embedded
参数被忽略。我将其更改为 NOT_EMBEDDED
因为如果您使用 EMBEDDED
阅读您的代码并且对 PDF 和 iText 一无所知的开发人员可能会感到困惑。他们可能会问:为什么参数说应该嵌入字体却没有嵌入?
BaseFont bf = BaseFont.CreateFont(BaseFont.COURIER_BOLD,BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
从右边开始写:
您正在使用数字定义比对:2
。我建议您不要在代码中使用数字,而是使用常量:ALIGN_RIGHT
。这样,我们看到您想要右对齐文本。
文本相对于您定义的坐标右对齐:
x = 155
y = 655
如果您对文本的位置不满意,您应该更改这些硬编码坐标。例如:增加 x
并减少 y
.
您可能希望文本相对于 table 单元格或图像的边框。如果是这种情况,您不应该对坐标进行硬编码。 在 SO 的另一个问题中讨论了检索图像的坐标。检索 table 的坐标很可能是不可能的。这完全取决于原始 PDF 的性质。