我们公司使用iText在某些pdf表单上标记一些水印文本(不是图像)。我注意到95%的表格正确显示水印,约5%没有。我测试了,复制了2个原始pdf文件,一个标记为ok,另一个没有问题,然后通过一个小程序测试,结果相同:一个得到标记,另一个没有。然后我尝试了最新版本的iText jar文件(版本5.0.6),同样的事情。我检查了pdf文件属性,安全设置等,似乎没有显示任何提示。结果文件确实改变了大小,并在执行程序后标记为“由iText版本改变....”。
下面是示例水印代码(使用itext jar版本2.1.7),注意传入的topText,mainText,bottonText参数,使得3行水印在pdf中显示为水印。
任何帮助表示赞赏!!
public class WatermarkGenerator {
private static int TEXT_TILT_ANGLE = 25;
private static Color MEDIUM_GRAY = new Color(160, 160, 160);
private static int SUPPORT_FONT_SIZE = 42;
private static int PRIMARY_FONT_SIZE = 54;
public static void addWaterMark(InputStream pdfInputStream,
OutputStream outputStream, String topText,
String mainText, String bottomText) throws Exception {
PdfReader reader = new PdfReader(pdfInputStream);
int numPages = reader.getNumberOfPages();
// Create a stamper that will copy the document to the output
// stream.
PdfStamper stamp = new PdfStamper(reader, outputStream);
int page=1;
BaseFont baseFont =
BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE,
BaseFont.WINANSI, BaseFont.EMBEDDED);
float width;
float height;
while (page <= numPages) {
PdfContentByte cb = stamp.getOverContent(page);
height = reader.getPageSizeWithRotation(page).getHeight() / 2;
width = reader.getPageSizeWithRotation(page).getWidth() / 2;
cb = stamp.getUnderContent(page);
cb.saveState();
cb.setColorFill(MEDIUM_GRAY);
// Top Text
cb.beginText();
cb.setFontAndSize(baseFont, SUPPORT_FONT_SIZE);
cb.showTextAligned(Element.ALIGN_CENTER, topText, width,
height+PRIMARY_FONT_SIZE+16, TEXT_TILT_ANGLE);
cb.endText();
// Primary Text
cb.beginText();
cb.setFontAndSize(baseFont, PRIMARY_FONT_SIZE);
cb.showTextAligned(Element.ALIGN_CENTER, mainText, width,
height, TEXT_TILT_ANGLE);
cb.endText();
// Bottom Text
cb.beginText();
cb.setFontAndSize(baseFont, SUPPORT_FONT_SIZE);
cb.showTextAligned(Element.ALIGN_CENTER, bottomText, width,
height-PRIMARY_FONT_SIZE-6, TEXT_TILT_ANGLE);
cb.endText();
cb.restoreState();
page++;
}
stamp.close();
}
}
答案 0 :(得分:2)
我们通过更改Adobe LifecycleSave文件选项解决了问题。 File-&gt; Save-&gt; properties-&gt;另存为,然后查看另存为类型,默认为Acrobat 7.0.5动态PDF表单文件,我们更改为使用7.0.5静态PDF表单文件(实际上任何静态表单文件工作)。保存在静态文件中的文件没有此水印消失问题。感谢Mark指出正确的方向。
答案 1 :(得分:1)
您正在使用underContent而不是overContent。不要那样做。它让你受到大白色矩形的摆布,一些人坚持要先画一些东西。这是一个不太好的PostScript解释器,并且多年来一直没有必要。
好的,看过你的PDF后,我发现问题在于这是一个基于XFA的表格(来自LiveCycle Designer)。 Acrobat可以(并且经常)根据它包含的XFA(一种xml)重建整个文件。这就是你的改变丢失的方式。当Acrobat从XFA重建PDF时,所有现有的PDF信息都会被调整,包括您的水印。
实现此功能的唯一方法是将水印定义为PDF中包含的XFA文件的一部分。
检测这些表格并不是那么难:
PdfReader reader = new PdfReader(...);
AcroFields acFields = reader.getAcroFields();
XfaForm xfaForm = acFields.getXfaForm();
if (xfaForm != null && xfaForm.isXfaPresent()) {
// Ohs nose.
throw new ItsATrapException("We can't repel XML of that magnitude!");
}
另一方面,修改它们可能是相当挑战,但here's the specs。
一旦你弄清楚需要改变什么,这只是XML操作的一个简单问题......但是“弄清楚”部分可能有趣。
好狩猎。