直接说问题,itext没有直接提供替换PDF中文本的接口(查看资料得到的结论是PDF不支持这种操作),不过存在解决思路: 在需要替换的文本上覆盖新的文本 。按照这个思路我们需要解决以下几个问题:

  • itext怎样增加白色底的覆盖层
  • 找到覆盖层的位置(左顶点的位置)和高度与宽带
  • 这样做的目的是什么了?也告诉下大家,比如:现在要你将业务数据导出成PDF存档,且PDF的模板有现成的。对我们写程序的来说,变化的只是部分数据,假如我们可以直接替换里面的数据,是不是可以节省我们的开发时间。

    1、itext怎样增加覆盖层?

    itext在自己的Demo中提供了很多案例代码,从中我们可以看到高亮的案例
    查看itext代码
    [java] view plain copy
  • * This example was written in answer to the question:
  • * http://stackoverflow.com/questions/33952183
  • package sandbox.stamper;
  • import com.itextpdf.text.BaseColor;
  • import com.itextpdf.text.DocumentException;
  • import com.itextpdf.text.pdf.PdfContentByte;
  • import com.itextpdf.text.pdf.PdfReader;
  • import com.itextpdf.text.pdf.PdfStamper;
  • import java.io.File;
  • import java.io.FileOutputStream;
  • import java.io.IOException;
  • * @author Bruno Lowagie (iText Software)
  • public class HighLightByAddingContent {
  • public static final String SRC = "resources/pdfs/hello.pdf";
  • public static final String DEST = "results/stamper/hello_highlighted.pdf";
  • public static void main(String[] args) throws IOException, DocumentException {
  • File file = new File(DEST);
  • file.getParentFile().mkdirs();
  • new HighLightByAddingContent().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));
  • PdfContentByte canvas = stamper.getUnderContent( 1);
  • canvas.saveState();
  • canvas.setColorFill(BaseColor.YELLOW);
  • canvas.rectangle( 36, 786, 66, 16);
  • canvas.fill();
  • canvas.restoreState();
  • stamper.close();
  • reader.close();
  • 这里可以在任意位置产生一个层,符合我们的“遮盖层”的要求,不过,通过测试发现此段代码存在一个问题点,它无法遮挡住文字,只是添加了一个背景层。为了达到我们的要求,我们只需要修改一处地方:
    [java] view plain copy
  • PdfContentByte canvas = stamper.getUnderContent( 1); //变成 PdfContentByte canvas = stamper.getOverContent(1);
  • 到目前为止,我们的遮盖层已添加,后面我们还需要的就是在新的遮盖层上写上自己的文字,代码如下:
    [java] view plain copy
  • /**********************************************************************
  • * <pre>
  • * FILE : HighLightByAddingContent.java
  • * CLASS : HighLightByAddingContent
  • * FUNCTION : TODO
  • *======================================================================
  • * CHANGE HISTORY LOG
  • *----------------------------------------------------------------------
  • * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
  • *----------------------------------------------------------------------
  • * DESCRIPTION:
  • * </pre>
  • ***********************************************************************/
  • package com.cx.itext;
  • import java.io.File;
  • import java.io.FileOutputStream;
  • import java.io.IOException;
  • import java.net.URLDecoder;
  • import com.itextpdf.text.BaseColor;
  • import com.itextpdf.text.DocumentException;
  • import com.itextpdf.text.Font;
  • import com.itextpdf.text.pdf.BaseFont;
  • import com.itextpdf.text.pdf.PdfContentByte;
  • import com.itextpdf.text.pdf.PdfReader;
  • import com.itextpdf.text.pdf.PdfStamper;
  • public class HighLightByAddingContent {
  • @SuppressWarnings( "deprecation")
  • public static final String SRC = URLDecoder.decode(HighLightByAddingContent. class.getResource( "ticket.pdf").getFile());
  • public static final String DEST = "I://ticket.pdf";
  • public static void main(String[] args) throws IOException, DocumentException {
  • File file = new File(DEST);
  • file.getParentFile().mkdirs();
  • new HighLightByAddingContent().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));
  • PdfContentByte canvas = stamper.getOverContent( 1);
  • float height= 595;
  • System.out.println(canvas.getHorizontalScaling());
  • float x,y;
  • x= 216;
  • y = height - 49.09F;
  • canvas.saveState();
  • canvas.setColorFill(BaseColor.WHITE);
  • canvas.rectangle(x, y- 5, 43, 15);
  • 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(), 10);
  • //设置字体的输出位置
  • canvas.setTextMatrix(x, y);
  • //要输出的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");
  • 2、找到覆盖层的位置(左顶点的位置)和高度与宽带

    我的第一个想法是通过工具得到替换文本的具体位置,虽然这个方法不怎么好,不过确实可行。使用到的工具是常用的Adobe Reader,以下是正常页面(PDF是网上搜的,百度key:“申请 filetype:pdf”):
    Adobe提供了测量工具,我们可以通过“编辑-->分析-->测量工具”看到如下页面:
    此时,我们虽然可以直接测量,但是测量默认显示的厘米,与itext需要设置的单位不一致,我们需要手工换算下(1英寸=72点)。不过,adobe可以帮我们省掉换算的工作,右键点击,出现以下选项(需要在测量功能下右键):
    “更改比例”可以帮助我们完成换算工作。(ps:“显示标尺”是一个不错的选项)。最后的画面如下:
    最后,需要提醒下,itext的Y是从下往上算的。
    这样得到位置是不是太不方便了 。那我们是否可以通过itext自动计算出我们需要的位置?代码如下(从网上COPY,不记得具体来源,支持作者)
    [java] view plain copy
  • /**********************************************************************
  • * <pre>
  • * FILE : Demo.java
  • * CLASS : Demo
  • * AUTHOR : caoxu-yiyang@qq.com
  • * FUNCTION : TODO
  • *======================================================================
  • * CHANGE HISTORY LOG
  • *----------------------------------------------------------------------
  • * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
  • *----------------------------------------------------------------------
  • *          |2016年11月9日|caoxu-yiyang@qq.com| Created |
  • * DESCRIPTION:
  • * </pre>
  • ***********************************************************************/
  • package com.cx.itext;
  • import java.io.IOException;
  • import com.itextpdf.awt.geom.Rectangle2D.Float;
  • import com.itextpdf.text.pdf.PdfReader;
  • import com.itextpdf.text.pdf.parser.ImageRenderInfo;
  • import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
  • import com.itextpdf.text.pdf.parser.RenderListener;
  • import com.itextpdf.text.pdf.parser.TextRenderInfo;
  • public class Demo
  • // 定义关键字
  • private static String KEY_WORD = "结算区分";
  • // 定义返回值
  • private static float[] resu = null;
  • // 定义返回页码
  • private static int i = 0;
  • public static void main(String[] args) {
  • float[] point = getKeyWords( "I://ticket_in.pdf");
  • * 返回关键字所在的坐标和页数 float[0] >> X float[1] >> Y float[2] >> page
  • private static float[] getKeyWords(String filePath)
  • PdfReader pdfReader = new PdfReader(filePath);
  • int pageNum = pdfReader.getNumberOfPages();
  • 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);
  • System.out.println( "h:"+boundingRectange.getHeight());
  • System.out.println( "w:"+boundingRectange.width);
  • System.out.println( "centerX:"+boundingRectange.getCenterX());
  • System.out.println( "centerY:"+boundingRectange.getCenterY());
  • System.out.println( "x:"+boundingRectange.getX());
  • System.out.println( "y:"+boundingRectange.getY());
  • System.out.println( "maxX:"+boundingRectange.getMaxX());
  • System.out.println( "maxY:"+boundingRectange.getMaxY());
  • System.out.println( "minX:"+boundingRectange.getMinX());
  • System.out.println( "minY:"+boundingRectange.getMinY());
  • 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;
  • 结合以上的,我们就可以写一个自动替换PDF文本的类,具体使用如下:
    [java] view plain copy
  • public static void main(String[] args) throws IOException, DocumentException {
  • PdfReplacer textReplacer = new PdfReplacer( "I://test.pdf");
  • textReplacer.replaceText( "陈坤", "小白");
  • textReplacer.replaceText( "本科", "社会大学");
  • textReplacer.replaceText( "0755-29493863", "15112345678");
  • textReplacer.toPdf( "I://ticket_out.pdf");

  • 原始PDF:
    替换之后的(红色背景只是方便大家看到差别):
    (第一次认真写博客,感觉感觉好花时间了,佩服那些坚持写博客的人~~)
  • /**********************************************************************
  • * <pre>
  • * FILE : PdfTextReplacer.java
  • * CLASS : PdfTextReplacer
  • * AUTHOR : caoxu-yiyang@qq.com
  • * FUNCTION : TODO
  • *======================================================================
  • * CHANGE HISTORY LOG
  • *----------------------------------------------------------------------
  • * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
  • *----------------------------------------------------------------------
  • *          |2016年11月8日|caoxu-yiyang@qq.com| Created |
  • * DESCRIPTION:
  • * </pre>
  • ***********************************************************************/
  • package com.cx.itext;
  • import java.io.ByteArrayOutputStream;
  • import java.io.FileInputStream;
  • import java.io.FileOutputStream;
  • import java.io.IOException;
  • import java.util.HashMap;
  • import java.util.Map;
  • import java.util.Map.Entry;
  • import java.util.Set;
  • import com.itextpdf.text.BaseColor;
  • import com.itextpdf.text.DocumentException;
  • import com.itextpdf.text.Font;
  • import com.itextpdf.text.log.Logger;
  • import com.itextpdf.text.log.LoggerFactory;
  • import com.itextpdf.text.pdf.BaseFont;
  • import com.itextpdf.text.pdf.PdfContentByte;
  • import com.itextpdf.text.pdf.PdfReader;
  • import com.itextpdf.text.pdf.PdfStamper;
  • * 替换PDF文件某个区域内的文本
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月8日
  • public class PdfReplacer {
  • private static final Logger logger = LoggerFactory.getLogger(PdfReplacer. class);
  • private int fontSize;
  • private Map<String, ReplaceRegion> replaceRegionMap = new HashMap<String, ReplaceRegion>();
  • private Map<String, Object> replaceTextMap = new HashMap<String, Object>();
  • private ByteArrayOutputStream output;
  • private PdfReader reader;
  • private PdfStamper stamper;
  • private PdfContentByte canvas;
  • private Font font;
  • public PdfReplacer( byte[] pdfBytes) throws DocumentException, IOException{
  • init(pdfBytes);
  • public PdfReplacer(String fileName) throws IOException, DocumentException{
  • FileInputStream in = null;
  • in = new FileInputStream(fileName);
  • byte[] pdfBytes = new byte[in.available()];
  • in.read(pdfBytes);
  • init(pdfBytes);
  • } finally{
  • in.close();
  • private void init( byte[] pdfBytes) throws DocumentException, IOException{
  • logger.info( "初始化开始");
  • reader = new PdfReader(pdfBytes);
  • output = new ByteArrayOutputStream();
  • stamper = new PdfStamper(reader, output);
  • canvas = stamper.getOverContent( 1);
  • setFont( 10);
  • logger.info( "初始化成功");
  • private void close() throws DocumentException, IOException{
  • if(reader != null){
  • reader.close();
  • if(output != null){
  • output.close();
  • output= null;
  • replaceRegionMap= null;
  • replaceTextMap= null;
  • public void replaceText( float x, float y, float w, float h, String text){
  • ReplaceRegion region = new ReplaceRegion(text); //用文本作为别名
  • region.setH(h);
  • region.setW(w);
  • region.setX(x);
  • region.setY(y);
  • addReplaceRegion(region);
  • this.replaceText(text, text);
  • public void replaceText(String name, String text){
  • this.replaceTextMap.put(name, text);
  • * 替换文本
  • * @throws IOException
  • * @throws DocumentException
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • private void process() throws DocumentException, IOException{
  • parseReplaceText();
  • canvas.saveState();
  • Set<Entry<String, ReplaceRegion>> entrys = replaceRegionMap.entrySet();
  • for (Entry<String, ReplaceRegion> entry : entrys) {
  • ReplaceRegion value = entry.getValue();
  • canvas.setColorFill(BaseColor.RED);
  • canvas.rectangle(value.getX(),value.getY(),value.getW(),value.getH());
  • canvas.fill();
  • canvas.restoreState();
  • //开始写入文本
  • canvas.beginText();
  • for (Entry<String, ReplaceRegion> entry : entrys) {
  • ReplaceRegion value = entry.getValue();
  • //设置字体
  • canvas.setFontAndSize(font.getBaseFont(), getFontSize());
  • canvas.setTextMatrix(value.getX(),value.getY()+ 2 /*修正背景与文本的相对位置*/);
  • canvas.showText((String) replaceTextMap.get(value.getAliasName()));
  • canvas.endText();
  • } finally{
  • if(stamper != null){
  • stamper.close();
  • * 未指定具体的替换位置时,系统自动查找位置
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • private void parseReplaceText() {
  • PdfPositionParse parse = new PdfPositionParse(reader);
  • Set<Entry<String, Object>> entrys = this.replaceTextMap.entrySet();
  • for (Entry<String, Object> entry : entrys) {
  • if( this.replaceRegionMap.get(entry.getKey()) == null){
  • parse.addFindText(entry.getKey());
  • try {
  • Map<String, ReplaceRegion> parseResult = parse.parse();
  • Set<Entry<String, ReplaceRegion>> parseEntrys = parseResult.entrySet();
  • for (Entry<String, ReplaceRegion> entry : parseEntrys) {
  • if(entry.getValue() != null){
  • this.replaceRegionMap.put(entry.getKey(), entry.getValue());
  • } catch (IOException e) {
  • logger.error(e.getMessage(), e);
  • * 生成新的PDF文件
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • * @param fileName
  • * @throws DocumentException
  • * @throws IOException
  • public void toPdf(String fileName) throws DocumentException, IOException{
  • FileOutputStream fileOutputStream = null;
  • process();
  • fileOutputStream = new FileOutputStream(fileName);
  • fileOutputStream.write(output.toByteArray());
  • fileOutputStream.flush();
  • } catch(IOException e){
  • logger.error(e.getMessage(), e);
  • throw e;
  • } finally{
  • if(fileOutputStream != null){
  • fileOutputStream.close();
  • close();
  • logger.info( "文件生成成功");
  • * 将生成的PDF文件转换成二进制数组
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • * @return
  • * @throws DocumentException
  • * @throws IOException
  • public byte[] toBytes() throws DocumentException, IOException{
  • process();
  • logger.info( "二进制数据生成成功");
  • return output.toByteArray();
  • } finally{
  • close();
  • * 添加替换区域
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • * @param replaceRegion
  • public void addReplaceRegion(ReplaceRegion replaceRegion){
  • this.replaceRegionMap.put(replaceRegion.getAliasName(), replaceRegion);
  • * 通过别名得到替换区域
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • * @param aliasName
  • * @return
  • public ReplaceRegion getReplaceRegion(String aliasName){
  • return this.replaceRegionMap.get(aliasName);
  • public int getFontSize() {
  • return fontSize;
  • * 设置字体大小
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • * @param fontSize
  • * @throws DocumentException
  • * @throws IOException
  • public void setFont( int fontSize) throws DocumentException, IOException{
  • if(fontSize != this.fontSize){
  • this.fontSize = fontSize;
  • BaseFont bf = BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
  • font = new Font(bf, this.fontSize,Font.BOLD);
  • public void setFont(Font font){
  • if(font == null){
  • throw new NullPointerException( "font is null");
  • this.font = font;
  • public static void main(String[] args) throws IOException, DocumentException {
  • PdfReplacer textReplacer = new PdfReplacer( "I://test.pdf");
  • textReplacer.replaceText( "陈坤", "小白");
  • textReplacer.replaceText( "本科", "社会大学");
  • textReplacer.replaceText( "0755-29493863", "15112345678");
  • textReplacer.toPdf( "I://ticket_out.pdf");
  • /**********************************************************************
  • * <pre>
  • * FILE : ReplaceRegion.java
  • * CLASS : ReplaceRegion
  • * AUTHOR : caoxu-yiyang@qq.com
  • * FUNCTION : TODO
  • *======================================================================
  • * CHANGE HISTORY LOG
  • *----------------------------------------------------------------------
  • * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
  • *----------------------------------------------------------------------
  • *          |2016年11月9日|caoxu-yiyang@qq.com| Created |
  • * DESCRIPTION:
  • * </pre>
  • ***********************************************************************/
  • package com.cx.itext;
  • * 需要替换的区域
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • public class ReplaceRegion {
  • private String aliasName;
  • private Float x;
  • private Float y;
  • private Float w;
  • private Float h;
  • public ReplaceRegion(String aliasName){
  • this.aliasName = aliasName;
  • * 替换区域的别名
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • * @return
  • public String getAliasName() {
  • return aliasName;
  • public void setAliasName(String aliasName) {
  • this.aliasName = aliasName;
  • public Float getX() {
  • return x;
  • public void setX(Float x) {
  • this.x = x;
  • public Float getY() {
  • return y;
  • public void setY(Float y) {
  • this.y = y;
  • public Float getW() {
  • return w;
  • public void setW(Float w) {
  • this.w = w;
  • public Float getH() {
  • return h;
  • public void setH(Float h) {
  • this.h = h;
  • /**********************************************************************
  • * <pre>
  • * FILE : PdfPositionParse.java
  • * CLASS : PdfPositionParse
  • * AUTHOR : caoxu-yiyang@qq.com
  • * FUNCTION : TODO
  • *======================================================================
  • * CHANGE HISTORY LOG
  • *----------------------------------------------------------------------
  • * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
  • *----------------------------------------------------------------------
  • *          |2016年11月9日|caoxu-yiyang@qq.com| Created |
  • * DESCRIPTION:
  • * </pre>
  • ***********************************************************************/
  • package com.cx.itext;
  • import java.io.FileInputStream;
  • import java.io.IOException;
  • import java.util.ArrayList;
  • import java.util.List;
  • import java.util.Map;
  • import com.cx.itext.listener.PositionRenderListener;
  • import com.itextpdf.text.pdf.PdfReader;
  • import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
  • * 解析PDF中文本的x,y位置
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • public class PdfPositionParse {
  • private PdfReader reader;
  • private List<String> findText = new ArrayList<String>(); //需要查找的文本
  • private PdfReaderContentParser parser;
  • public PdfPositionParse(String fileName) throws IOException{
  • FileInputStream in = null;
  • in = new FileInputStream(fileName);
  • byte[] bytes = new byte[in.available()];
  • in.read(bytes);
  • init(bytes);
  • } finally{
  • in.close();
  • public PdfPositionParse( byte[] bytes) throws IOException{
  • init(bytes);
  • private boolean needClose = true;
  • * 传递进来的reader不会在PdfPositionParse结束时关闭
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • * @param reader
  • public PdfPositionParse(PdfReader reader){
  • this.reader = reader;
  • parser = new PdfReaderContentParser(reader);
  • needClose = false;
  • public void addFindText(String text){
  • this.findText.add(text);
  • private void init( byte[] bytes) throws IOException {
  • reader = new PdfReader(bytes);
  • parser = new PdfReaderContentParser(reader);
  • * 解析文本
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • * @throws IOException
  • public Map<String, ReplaceRegion> parse() throws IOException{
  • if( this.findText.size() == 0){
  • throw new NullPointerException( "没有需要查找的文本");
  • PositionRenderListener listener = new PositionRenderListener( this.findText);
  • parser.processContent( 1, listener);
  • return listener.getResult();
  • } finally{
  • if(reader != null && needClose){
  • reader.close();
  • /**********************************************************************
  • * <pre>
  • * FILE : PositionRenderListener.java
  • * CLASS : PositionRenderListener
  • * AUTHOR : caoxu-yiyang@qq.com
  • * FUNCTION : TODO
  • *======================================================================
  • * CHANGE HISTORY LOG
  • *----------------------------------------------------------------------
  • * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
  • *----------------------------------------------------------------------
  • *          |2016年11月9日|caoxu-yiyang@qq.com| Created |
  • * DESCRIPTION:
  • * </pre>
  • ***********************************************************************/
  • package com.cx.itext.listener;
  • import java.util.HashMap;
  • import java.util.List;
  • import java.util.Map;
  • import com.cx.itext.ReplaceRegion;
  • import com.itextpdf.awt.geom.Rectangle2D.Float;
  • import com.itextpdf.text.pdf.parser.ImageRenderInfo;
  • import com.itextpdf.text.pdf.parser.RenderListener;
  • import com.itextpdf.text.pdf.parser.TextRenderInfo;
  • * pdf渲染监听,当找到渲染的文本时,得到文本的坐标x,y,w,h
  • * @user : caoxu-yiyang@qq.com
  • * @date : 2016年11月9日
  • public class PositionRenderListener implements RenderListener{
  • private List<String> findText;
  • private float defaultH; ///出现无法取到值的情况,默认为12
  • private float fixHeight; //可能出现无法完全覆盖的情况,提供修正的参数,默认为2
  • public PositionRenderListener(List<String> findText, float defaultH, float fixHeight) {
  • this.findText = findText;
  • this.defaultH = defaultH;
  • this.fixHeight = fixHeight;
  • public PositionRenderListener(List<String> findText) {
  • this.findText = findText;
  • this.defaultH = 12;
  • this.fixHeight = 2;
  • @Override
  • public void beginTextBlock() {
  • @Override
  • public void endTextBlock() {
  • @Override
  • public void renderImage(ImageRenderInfo imageInfo) {
  • private Map<String, ReplaceRegion> result = new HashMap<String, ReplaceRegion>();
  • @Override
  • public void renderText(TextRenderInfo textInfo) {
  • String text = textInfo.getText();
  • for (String keyWord : findText) {
  • if ( null != text && text.equals(keyWord)){
  • Float bound = textInfo.getBaseline().getBoundingRectange();
  • ReplaceRegion region = new ReplaceRegion(keyWord);
  • region.setH(bound.height == 0 ? defaultH : bound.height);
  • region.setW(bound.width);
  • region.setX(bound.x);
  • region.setY(bound.y- this.fixHeight);
  • result.put(keyWord, region);
  • public Map<String, ReplaceRegion> getResult() {
  • for (String key : findText) { //补充没有找到的数据
  • if( this.result.get(key) == null){
  • this.result.put(key, null);
  • return this.result;
  • 我用到的jar包如下:


    大家可以从官网下载,可以构建maven项目省去自己找包的麻烦。如果没有用maven又想下载具体的jar包,可以直接访问maven仓库下载: http://mvnrepository.com/