itext替换PDF的原理就是找到要替换的文字,然后计算他的位置,在哪个位置上生成覆盖层,然后在覆盖层上写内容。
从网上看到的自动计算PDF中文字的位置方法。
public class PdfConversion {
// 定义关键字
private static String KEY_WORD = "张三";
// 定义返回值
private static float[] resu = null;
// 定义返回页码
private static int i = 0;
/*
* 返回关键字所在的坐标和页数 float[0] >> X; float[1] >> Y; float[2] >> page;
*/
public static float[] getKeyWords(String filePath)
{
try
{
PdfReader pdfReader = new PdfReader(filePath);
int pageNum = pdfReader.getNumberOfPages();
System.out.println(pageNum);
PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(
pdfReader);
// 下标从1开始
for (i = 1; i <= pageNum; i++)
{
pdfReaderContentParser.processContent(i, new RenderListener()
{
@Override
public void renderText(TextRenderInfo textRenderInfo)
{
String text = textRenderInfo.getText();
if (null != text && text.contains(KEY_WORD))
{
Float boundingRectange = textRenderInfo
.getBaseline().getBoundingRectange();
resu = new float[3];
System.out.println("======="+text);
resu[0] = boundingRectange.x;
resu[1] = boundingRectange.y;
resu[2] = i;
}
}
@Override
public void renderImage(ImageRenderInfo arg0)
{
}
@Override
public void endTextBlock()
{
}
@Override
public void beginTextBlock()
{
}
});
}
} catch (IOException e)
{
e.printStackTrace();
}
return resu;
}
}
然后是覆盖层的方法
public class PdfConversion1 {
// @SuppressWarnings("deprecation")
public static final String SRC = "C:/Users/tym/Desktop/template.pdf";
public static final String DEST = "C:/Users/tym/Desktop/test1.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new PdfConversion1().manipulatePdf(SRC, DEST);
}
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
float[] result = PdfConversion.getKeyWords(src); //1
PdfContentByte canvas = stamper.getOverContent((int) result[2]);
// float height=595;
// System.out.println(canvas.getHorizontalScaling());
float x,y;
x= result[0];//2
y = result[1];//3
canvas.saveState();
canvas.setColorFill(BaseColor.WHITE);
canvas.rectangle(x, y, 40, 20);//设置覆盖面的大小
canvas.fill();
canvas.restoreState();
//开始写入文本
canvas.beginText();
//BaseFont bf = BaseFont.createFont(URLDecoder.decode(CutAndPaste.class.getResource("/AdobeSongStd-Light.otf").getFile()), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
Font font = new Font(bf,10,Font.BOLD);
//设置字体和大小
canvas.setFontAndSize(font.getBaseFont(), 15);
//设置字体的输出位置
canvas.setTextMatrix(x, y-1);
//要输出的text
canvas.showText("田田田" );
//设置字体的输出位置
canvas.setFontAndSize(font.getBaseFont(), 20);
canvas.setTextMatrix(x, y-90);
//要输出的text
canvas.showText("多退少补" );
canvas.endText();
stamper.close();
reader.close();
System.out.println("complete");
}
}
就可以实现替换了。不过缺点是假如你要复制的话,复制的还是底层的内容,而不是你覆盖的新内容。