我创建了2个可填写表格的pdf文件,一个将用作客户订单表格,另一个将在内部用作生产表格。每个pdf都有相同的字段(每个字段的名称和类型相同)。我编写了一个应用程序(除其他事项外)使用iTextSharp读取给定客户订单中的所有字段,创建新的生产表,并填写订单中的所有数据。所有这些对于文本和日期字段(字符串数据)都可以顺利运行。但是,每个pdf上都有一个图像字段,我需要从定单上的图像字段中获取图像并将其复制到生产单上的图像字段中。这就是我要挂断电话的地方。
我可以使用pr.Acrofields.GetFieldItem("imageFieldName");
来将图像作为Acrofields.item
对象,但是我似乎无法让iTextSharp允许我使用{{1} }方法,因为它只需要一个字符串。
也许有一种方法可以获取图像数据并将其存储为临时.jpg或.bmp文件,然后将其插入到生产工作表的图像字段中?还是我要解决所有这些错误?
答案 0 :(得分:1)
正如评论中已经提到的, pdf格式没有任何图像字段。一些pdf设计师允许使用例如一个按钮以及一些JavaScript。但是,由于仅模拟该字段,所以没有图像值。对于您的两个文档来说确实如此。
因此,要从源表单按钮检索图像,我们不能采用按钮 value ,而必须从按钮 appearance 中提取图像。我们使用itext解析器名称空间类和自定义ImageRenderListener
渲染监听器类来收集位图图像来进行此操作。
此外,要将图像设置为目标表单按钮,我们也不能简单地设置按钮 value ,而必须设置按钮 appearance 。我们使用iText AcroFields
方法GetNewPushbuttonFromField
和ReplacePushbuttonField
来做到这一点。
ImageRenderListener
渲染侦听器类此渲染侦听器所做的只是收集位图图像:
public class ImageRenderListener : IRenderListener
{
public List<System.Drawing.Image> Images = new List<System.Drawing.Image>();
public void BeginTextBlock()
{ }
public void EndTextBlock()
{ }
public void RenderText(TextRenderInfo renderInfo)
{ }
public void RenderImage(ImageRenderInfo renderInfo)
{
PdfImageObject imageObject = renderInfo.GetImage();
if (imageObject == null)
{
Console.WriteLine("Image {0} could not be read.", renderInfo.GetRef().Number);
}
else
{
Images.Add(imageObject.GetDrawingImage());
}
}
}
Copy
方法此方法从源阅读器表单元素检索第一张图像,并将其添加到目标压模表单元素:
void Copy(PdfReader source, string sourceButton, PdfStamper target, string targetButton)
{
PdfStream xObject = (PdfStream) PdfReader.GetPdfObjectRelease(source.AcroFields.GetNormalAppearance(sourceButton));
PdfDictionary resources = xObject.GetAsDict(PdfName.RESOURCES);
ImageRenderListener strategy = new ImageRenderListener();
PdfContentStreamProcessor processor = new PdfContentStreamProcessor(strategy);
processor.ProcessContent(ContentByteUtils.GetContentBytesFromContentObject(xObject), resources);
System.Drawing.Image drawingImage = strategy.Images.First();
Image image = Image.GetInstance(drawingImage, drawingImage.RawFormat);
PushbuttonField button = target.AcroFields.GetNewPushbuttonFromField(targetButton);
button.Image = image;
target.AcroFields.ReplacePushbuttonField(targetButton, button.Field);
}
我使用Adobe Acrobat Reader将图像填充到源文档中
,并将此文档另存为Customer Order Form-Willi.pdf
。
然后我应用了上述复制方法:
String source = @"Customer Order Form-Willi.pdf";
String dest = @"Production Sheet.pdf";
String target = @"Production Sheet-withImage.pdf";
using (PdfReader sourceReader = new PdfReader(source))
using (PdfReader destReader = new PdfReader(dest))
using (PdfStamper targetStamper = new PdfStamper(destReader, File.Create(target), (char)0, true))
{
Copy(sourceReader, "proofImage", targetStamper, "proofImage");
}
Production Sheet-withImage.pdf
中的结果:
上面的代码非常乐观,不包含任何合理性检查。对于生产而言,您应该使它更具防御性,并检查null
值,空列表等。