相关文章推荐
活泼的椅子  ·  js合并两个map_js ...·  1 年前    · 
温文尔雅的蘑菇  ·  access vba ...·  1 年前    · 
耍酷的硬盘  ·  asp.net uploadfile ...·  1 年前    · 
温暖的西瓜  ·  .NET、C#、.NET ...·  1 年前    · 

直接说问题,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();
  • 这里可以在任意位置产生一个层,符合我们的“遮盖层”的要求,不过,通过测试发现此段代码存在一个问题点,它无法遮挡住文字,只是添加了一个背景层。为了达到我们的要求,我们只需要修改一处地方:
    1. PdfContentByte canvas = stamper.getUnderContent( 1); //变成 PdfContentByte canvas = stamper.getOverContent(1); 到目前为止,我们的遮盖层已添加,后面我们还需要的就是在新的遮盖层上写上自己的文字,代码如下:
      1. /**********************************************************************
      2. * <pre>
      3. * FILE : HighLightByAddingContent.java
      4. * CLASS : HighLightByAddingContent
      5. * FUNCTION : TODO
      6. *======================================================================
      7. * CHANGE HISTORY LOG
      8. *----------------------------------------------------------------------
      9. * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
      10. *----------------------------------------------------------------------
      11. * DESCRIPTION:
      12. * </pre>
      13. ***********************************************************************/
      14. package com.cx.itext;
      15. import java.io.File;
      16. import java.io.FileOutputStream;
      17. import java.io.IOException;
      18. import java.net.URLDecoder;
      19. import com.itextpdf.text.BaseColor;
      20. import com.itextpdf.text.DocumentException;
      21. import com.itextpdf.text.Font;
      22. import com.itextpdf.text.pdf.BaseFont;
      23. import com.itextpdf.text.pdf.PdfContentByte;
      24. import com.itextpdf.text.pdf.PdfReader;
      25. import com.itextpdf.text.pdf.PdfStamper;
      26. public class HighLightByAddingContent {
      27. @SuppressWarnings( "deprecation")
      28. public static final String SRC = URLDecoder.decode(HighLightByAddingContent. class.getResource( "ticket.pdf").getFile());
      29. public static final String DEST = "I://ticket.pdf";
      30. public static void main(String[] args) throws IOException, DocumentException {
      31. File file = new File(DEST);
      32. file.getParentFile().mkdirs();
      33. new HighLightByAddingContent().manipulatePdf(SRC, DEST);
      34. public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
      35. PdfReader reader = new PdfReader(src);
      36. PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
      37. PdfContentByte canvas = stamper.getOverContent( 1);
      38. float height= 595;
      39. System.out.println(canvas.getHorizontalScaling());
      40. float x,y;
      41. x= 216;
      42. y = height - 49.09F;
      43. canvas.saveState();
      44. canvas.setColorFill(BaseColor.WHITE);
      45. canvas.rectangle(x, y- 5, 43, 15);
      46. canvas.fill();
      47. canvas.restoreState();
      48. //开始写入文本
      49. canvas.beginText();
      50. //BaseFont bf = BaseFont.createFont(URLDecoder.decode(CutAndPaste.class.getResource("/AdobeSongStd-Light.otf").getFile()), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
      51. BaseFont bf = BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
      52. Font font = new Font(bf, 10,Font.BOLD);
      53. //设置字体和大小
      54. canvas.setFontAndSize(font.getBaseFont(), 10);
      55. //设置字体的输出位置
      56. canvas.setTextMatrix(x, y);
      57. //要输出的text
      58. canvas.showText( "多退少补" );
      59. //设置字体的输出位置
      60. canvas.setFontAndSize(font.getBaseFont(), 20);
      61. canvas.setTextMatrix(x, y- 90);
      62. //要输出的text
      63. canvas.showText( "多退少补" );
      64. canvas.endText();
      65. stamper.close();
      66. reader.close();
      67. System.out.println( "complete"); 2、找到覆盖层的位置(左顶点的位置)和高度与宽带
        我的第一个想法是通过工具得到替换文本的具体位置,虽然这个方法不怎么好,不过确实可行。使用到的工具是常用的Adobe Reader,以下是正常页面(PDF是网上搜的,百度key:“申请 filetype:pdf”):
        Adobe提供了测量工具,我们可以通过“编辑-->分析-->测量工具”看到如下页面:
        此时,我们虽然可以直接测量,但是测量默认显示的厘米,与itext需要设置的单位不一致,我们需要手工换算下(1英寸=72点)。不过,adobe可以帮我们省掉换算的工作,右键点击,出现以下选项(需要在测量功能下右键):
        “更改比例”可以帮助我们完成换算工作。(ps:“显示标尺”是一个不错的选项)。最后的画面如下:
        最后,需要提醒下,itext的Y是从下往上算的。
        这样得到位置是不是太不方便了 。那我们是否可以通过itext自动计算出我们需要的位置?代码如下(从网上COPY,不记得具体来源,支持作者)
        1. /**********************************************************************
        2. * <pre>
        3. * FILE : Demo.java
        4. * CLASS : Demo
        5. * AUTHOR : caoxu-yiyang@qq.com
        6. * FUNCTION : TODO
        7. *======================================================================
        8. * CHANGE HISTORY LOG
        9. *----------------------------------------------------------------------
        10. * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
        11. *----------------------------------------------------------------------
        12. *          |2016年11月9日|caoxu-yiyang@qq.com| Created |
        13. * DESCRIPTION:
        14. * </pre>
        15. ***********************************************************************/
        16. package com.cx.itext;
        17. import java.io.IOException;
        18. import com.itextpdf.awt.geom.Rectangle2D.Float;
        19. import com.itextpdf.text.pdf.PdfReader;
        20. import com.itextpdf.text.pdf.parser.ImageRenderInfo;
        21. import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
        22. import com.itextpdf.text.pdf.parser.RenderListener;
        23. import com.itextpdf.text.pdf.parser.TextRenderInfo;
        24. public class Demo
        25. // 定义关键字
        26. private static String KEY_WORD = "结算区分";
        27. // 定义返回值
        28. private static float[] resu = null;
        29. // 定义返回页码
        30. private static int i = 0;
        31. public static void main(String[] args) {
        32. float[] point = getKeyWords( "I://ticket_in.pdf");
        33. * 返回关键字所在的坐标和页数 float[0] >> X float[1] >> Y float[2] >> page
        34. private static float[] getKeyWords(String filePath)
        35. PdfReader pdfReader = new PdfReader(filePath);
        36. int pageNum = pdfReader.getNumberOfPages();
        37. PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(
        38. pdfReader);
        39. // 下标从1开始
        40. for (i = 1; i <= pageNum; i++)
        41. pdfReaderContentParser.processContent(i, new RenderListener()
        42. @Override
        43. public void renderText(TextRenderInfo textRenderInfo)
        44. String text = textRenderInfo.getText();
        45. if ( null != text && text.contains(KEY_WORD))
        46. Float boundingRectange = textRenderInfo
        47. .getBaseline().getBoundingRectange();
        48. resu = new float[ 3];
        49. System.out.println( "======="+text);
        50. System.out.println( "h:"+boundingRectange.getHeight());
        51. System.out.println( "w:"+boundingRectange.width);
        52. System.out.println( "centerX:"+boundingRectange.getCenterX());
        53. System.out.println( "centerY:"+boundingRectange.getCenterY());
        54. System.out.println( "x:"+boundingRectange.getX());
        55. System.out.println( "y:"+boundingRectange.getY());
        56. System.out.println( "maxX:"+boundingRectange.getMaxX());
        57. System.out.println( "maxY:"+boundingRectange.getMaxY());
        58. System.out.println( "minX:"+boundingRectange.getMinX());
        59. System.out.println( "minY:"+boundingRectange.getMinY());
        60. resu[ 0] = boundingRectange.x;
        61. resu[ 1] = boundingRectange.y;
        62. resu[ 2] = i;
        63. @Override
        64. public void renderImage(ImageRenderInfo arg0)
        65. @Override
        66. public void endTextBlock()
        67. @Override
        68. public void beginTextBlock()
        69. } catch (IOException e)
        70. e.printStackTrace();
        71. return resu; 结合以上的,我们就可以写一个自动替换PDF文本的类,具体使用如下:
          1. public static void main(String[] args) throws IOException, DocumentException {
          2. PdfReplacer textReplacer = new PdfReplacer( "I://test.pdf");
          3. textReplacer.replaceText( "陈坤", "小白");
          4. textReplacer.replaceText( "本科", "社会大学");
          5. textReplacer.replaceText( "0755-29493863", "15112345678");
          6. textReplacer.toPdf( "I://ticket_out.pdf");
            原始PDF:
            替换之后的(红色背景只是方便大家看到差别):
            (第一次认真写博客,感觉感觉好花时间了,佩服那些坚持写博客的人~~)
            1. /**********************************************************************
            2. * <pre>
            3. * FILE : PdfTextReplacer.java
            4. * CLASS : PdfTextReplacer
            5. * AUTHOR : caoxu-yiyang@qq.com
            6. * FUNCTION : TODO
            7. *======================================================================
            8. * CHANGE HISTORY LOG
            9. *----------------------------------------------------------------------
            10. * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
            11. *----------------------------------------------------------------------
            12. *          |2016年11月8日|caoxu-yiyang@qq.com| Created |
            13. * DESCRIPTION:
            14. * </pre>
            15. ***********************************************************************/
            16. package com.cx.itext;
            17. import java.io.ByteArrayOutputStream;
            18. import java.io.FileInputStream;
            19. import java.io.FileOutputStream;
            20. import java.io.IOException;
            21. import java.util.HashMap;
            22. import java.util.Map;
            23. import java.util.Map.Entry;
            24. import java.util.Set;
            25. import com.itextpdf.text.BaseColor;
            26. import com.itextpdf.text.DocumentException;
            27. import com.itextpdf.text.Font;
            28. import com.itextpdf.text.log.Logger;
            29. import com.itextpdf.text.log.LoggerFactory;
            30. import com.itextpdf.text.pdf.BaseFont;
            31. import com.itextpdf.text.pdf.PdfContentByte;
            32. import com.itextpdf.text.pdf.PdfReader;
            33. import com.itextpdf.text.pdf.PdfStamper;
            34. * 替换PDF文件某个区域内的文本
            35. * @user : caoxu-yiyang@qq.com
            36. * @date : 2016年11月8日
            37. public class PdfReplacer {
            38. private static final Logger logger = LoggerFactory.getLogger(PdfReplacer. class);
            39. private int fontSize;
            40. private Map<String, ReplaceRegion> replaceRegionMap = new HashMap<String, ReplaceRegion>();
            41. private Map<String, Object> replaceTextMap = new HashMap<String, Object>();
            42. private ByteArrayOutputStream output;
            43. private PdfReader reader;
            44. private PdfStamper stamper;
            45. private PdfContentByte canvas;
            46. private Font font;
            47. public PdfReplacer( byte[] pdfBytes) throws DocumentException, IOException{
            48. init(pdfBytes);
            49. public PdfReplacer(String fileName) throws IOException, DocumentException{
            50. FileInputStream in = null;
            51. in = new FileInputStream(fileName);
            52. byte[] pdfBytes = new byte[in.available()];
            53. in.read(pdfBytes);
            54. init(pdfBytes);
            55. } finally{
            56. in.close();
            57. private void init( byte[] pdfBytes) throws DocumentException, IOException{
            58. logger.info( "初始化开始");
            59. reader = new PdfReader(pdfBytes);
            60. output = new ByteArrayOutputStream();
            61. stamper = new PdfStamper(reader, output);
            62. canvas = stamper.getOverContent( 1);
            63. setFont( 10);
            64. logger.info( "初始化成功");
            65. private void close() throws DocumentException, IOException{
            66. if(reader != null){
            67. reader.close();
            68. if(output != null){
            69. output.close();
            70. output= null;
            71. replaceRegionMap= null;
            72. replaceTextMap= null;
            73. public void replaceText( float x, float y, float w, float h, String text){
            74. ReplaceRegion region = new ReplaceRegion(text); //用文本作为别名
            75. region.setH(h);
            76. region.setW(w);
            77. region.setX(x);
            78. region.setY(y);
            79. addReplaceRegion(region);
            80. this.replaceText(text, text);
            81. public void replaceText(String name, String text){
            82. this.replaceTextMap.put(name, text);
            83. * 替换文本
            84. * @throws IOException
            85. * @throws DocumentException
            86. * @user : caoxu-yiyang@qq.com
            87. * @date : 2016年11月9日
            88. private void process() throws DocumentException, IOException{
            89. parseReplaceText();
            90. canvas.saveState();
            91. Set<Entry<String, ReplaceRegion>> entrys = replaceRegionMap.entrySet();
            92. for (Entry<String, ReplaceRegion> entry : entrys) {
            93. ReplaceRegion value = entry.getValue();
            94. canvas.setColorFill(BaseColor.RED);
            95. canvas.rectangle(value.getX(),value.getY(),value.getW(),value.getH());
            96. canvas.fill();
            97. canvas.restoreState();
            98. //开始写入文本
            99. canvas.beginText();
            100. for (Entry<String, ReplaceRegion> entry : entrys) {
            101. ReplaceRegion value = entry.getValue();
            102. //设置字体
            103. canvas.setFontAndSize(font.getBaseFont(), getFontSize());
            104. canvas.setTextMatrix(value.getX(),value.getY()+ 2 /*修正背景与文本的相对位置*/);
            105. canvas.showText((String) replaceTextMap.get(value.getAliasName()));
            106. canvas.endText();
            107. } finally{
            108. if(stamper != null){
            109. stamper.close();
            110. * 未指定具体的替换位置时,系统自动查找位置
            111. * @user : caoxu-yiyang@qq.com
            112. * @date : 2016年11月9日
            113. private void parseReplaceText() {
            114. PdfPositionParse parse = new PdfPositionParse(reader);
            115. Set<Entry<String, Object>> entrys = this.replaceTextMap.entrySet();
            116. for (Entry<String, Object> entry : entrys) {
            117. if( this.replaceRegionMap.get(entry.getKey()) == null){
            118. parse.addFindText(entry.getKey());
            119. try {
            120. Map<String, ReplaceRegion> parseResult = parse.parse();
            121. Set<Entry<String, ReplaceRegion>> parseEntrys = parseResult.entrySet();
            122. for (Entry<String, ReplaceRegion> entry : parseEntrys) {
            123. if(entry.getValue() != null){
            124. this.replaceRegionMap.put(entry.getKey(), entry.getValue());
            125. } catch (IOException e) {
            126. logger.error(e.getMessage(), e);
            127. * 生成新的PDF文件
            128. * @user : caoxu-yiyang@qq.com
            129. * @date : 2016年11月9日
            130. * @param fileName
            131. * @throws DocumentException
            132. * @throws IOException
            133. public void toPdf(String fileName) throws DocumentException, IOException{
            134. FileOutputStream fileOutputStream = null;
            135. process();
            136. fileOutputStream = new FileOutputStream(fileName);
            137. fileOutputStream.write(output.toByteArray());
            138. fileOutputStream.flush();
            139. } catch(IOException e){
            140. logger.error(e.getMessage(), e);
            141. throw e;
            142. } finally{
            143. if(fileOutputStream != null){
            144. fileOutputStream.close();
            145. close();
            146. logger.info( "文件生成成功");
            147. * 将生成的PDF文件转换成二进制数组
            148. * @user : caoxu-yiyang@qq.com
            149. * @date : 2016年11月9日
            150. * @return
            151. * @throws DocumentException
            152. * @throws IOException
            153. public byte[] toBytes() throws DocumentException, IOException{
            154. process();
            155. logger.info( "二进制数据生成成功");
            156. return output.toByteArray();
            157. } finally{
            158. close();
            159. * 添加替换区域
            160. * @user : caoxu-yiyang@qq.com
            161. * @date : 2016年11月9日
            162. * @param replaceRegion
            163. public void addReplaceRegion(ReplaceRegion replaceRegion){
            164. this.replaceRegionMap.put(replaceRegion.getAliasName(), replaceRegion);
            165. * 通过别名得到替换区域
            166. * @user : caoxu-yiyang@qq.com
            167. * @date : 2016年11月9日
            168. * @param aliasName
            169. * @return
            170. public ReplaceRegion getReplaceRegion(String aliasName){
            171. return this.replaceRegionMap.get(aliasName);
            172. public int getFontSize() {
            173. return fontSize;
            174. * 设置字体大小
            175. * @user : caoxu-yiyang@qq.com
            176. * @date : 2016年11月9日
            177. * @param fontSize
            178. * @throws DocumentException
            179. * @throws IOException
            180. public void setFont( int fontSize) throws DocumentException, IOException{
            181. if(fontSize != this.fontSize){
            182. this.fontSize = fontSize;
            183. BaseFont bf = BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            184. font = new Font(bf, this.fontSize,Font.BOLD);
            185. public void setFont(Font font){
            186. if(font == null){
            187. throw new NullPointerException( "font is null");
            188. this.font = font;
            189. public static void main(String[] args) throws IOException, DocumentException {
            190. PdfReplacer textReplacer = new PdfReplacer( "I://test.pdf");
            191. textReplacer.replaceText( "陈坤", "小白");
            192. textReplacer.replaceText( "本科", "社会大学");
            193. textReplacer.replaceText( "0755-29493863", "15112345678");
            194. textReplacer.toPdf( "I://ticket_out.pdf");
              1. /**********************************************************************
              2. * <pre>
              3. * FILE : ReplaceRegion.java
              4. * CLASS : ReplaceRegion
              5. * AUTHOR : caoxu-yiyang@qq.com
              6. * FUNCTION : TODO
              7. *======================================================================
              8. * CHANGE HISTORY LOG
              9. *----------------------------------------------------------------------
              10. * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
              11. *----------------------------------------------------------------------
              12. *          |2016年11月9日|caoxu-yiyang@qq.com| Created |
              13. * DESCRIPTION:
              14. * </pre>
              15. ***********************************************************************/
              16. package com.cx.itext;
              17. * 需要替换的区域
              18. * @user : caoxu-yiyang@qq.com
              19. * @date : 2016年11月9日
              20. public class ReplaceRegion {
              21. private String aliasName;
              22. private Float x;
              23. private Float y;
              24. private Float w;
              25. private Float h;
              26. public ReplaceRegion(String aliasName){
              27. this.aliasName = aliasName;
              28. * 替换区域的别名
              29. * @user : caoxu-yiyang@qq.com
              30. * @date : 2016年11月9日
              31. * @return
              32. public String getAliasName() {
              33. return aliasName;
              34. public void setAliasName(String aliasName) {
              35. this.aliasName = aliasName;
              36. public Float getX() {
              37. return x;
              38. public void setX(Float x) {
              39. this.x = x;
              40. public Float getY() {
              41. return y;
              42. public void setY(Float y) {
              43. this.y = y;
              44. public Float getW() {
              45. return w;
              46. public void setW(Float w) {
              47. this.w = w;
              48. public Float getH() {
              49. return h;
              50. public void setH(Float h) {
              51. this.h = h;
                1. /**********************************************************************
                2. * <pre>
                3. * FILE : PdfPositionParse.java
                4. * CLASS : PdfPositionParse
                5. * AUTHOR : caoxu-yiyang@qq.com
                6. * FUNCTION : TODO
                7. *======================================================================
                8. * CHANGE HISTORY LOG
                9. *----------------------------------------------------------------------
                10. * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
                11. *----------------------------------------------------------------------
                12. *          |2016年11月9日|caoxu-yiyang@qq.com| Created |
                13. * DESCRIPTION:
                14. * </pre>
                15. ***********************************************************************/
                16. package com.cx.itext;
                17. import java.io.FileInputStream;
                18. import java.io.IOException;
                19. import java.util.ArrayList;
                20. import java.util.List;
                21. import java.util.Map;
                22. import com.cx.itext.listener.PositionRenderListener;
                23. import com.itextpdf.text.pdf.PdfReader;
                24. import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
                25. * 解析PDF中文本的x,y位置
                26. * @user : caoxu-yiyang@qq.com
                27. * @date : 2016年11月9日
                28. public class PdfPositionParse {
                29. private PdfReader reader;
                30. private List<String> findText = new ArrayList<String>(); //需要查找的文本
                31. private PdfReaderContentParser parser;
                32. public PdfPositionParse(String fileName) throws IOException{
                33. FileInputStream in = null;
                34. in = new FileInputStream(fileName);
                35. byte[] bytes = new byte[in.available()];
                36. in.read(bytes);
                37. init(bytes);
                38. } finally{
                39. in.close();
                40. public PdfPositionParse( byte[] bytes) throws IOException{
                41. init(bytes);
                42. private boolean needClose = true;
                43. * 传递进来的reader不会在PdfPositionParse结束时关闭
                44. * @user : caoxu-yiyang@qq.com
                45. * @date : 2016年11月9日
                46. * @param reader
                47. public PdfPositionParse(PdfReader reader){
                48. this.reader = reader;
                49. parser = new PdfReaderContentParser(reader);
                50. needClose = false;
                51. public void addFindText(String text){
                52. this.findText.add(text);
                53. private void init( byte[] bytes) throws IOException {
                54. reader = new PdfReader(bytes);
                55. parser = new PdfReaderContentParser(reader);
                56. * 解析文本
                57. * @user : caoxu-yiyang@qq.com
                58. * @date : 2016年11月9日
                59. * @throws IOException
                60. public Map<String, ReplaceRegion> parse() throws IOException{
                61. if( this.findText.size() == 0){
                62. throw new NullPointerException( "没有需要查找的文本");
                63. PositionRenderListener listener = new PositionRenderListener( this.findText);
                64. parser.processContent( 1, listener);
                65. return listener.getResult();
                66. } finally{
                67. if(reader != null && needClose){
                68. reader.close();
                  1. /**********************************************************************
                  2. * <pre>
                  3. * FILE : PositionRenderListener.java
                  4. * CLASS : PositionRenderListener
                  5. * AUTHOR : caoxu-yiyang@qq.com
                  6. * FUNCTION : TODO
                  7. *======================================================================
                  8. * CHANGE HISTORY LOG
                  9. *----------------------------------------------------------------------
                  10. * MOD. NO.|   DATE   |   NAME  | REASON  | CHANGE REQ.
                  11. *----------------------------------------------------------------------
                  12. *          |2016年11月9日|caoxu-yiyang@qq.com| Created |
                  13. * DESCRIPTION:
                  14. * </pre>
                  15. ***********************************************************************/
                  16. package com.cx.itext.listener;
                  17. import java.util.HashMap;
                  18. import java.util.List;
                  19. import java.util.Map;
                  20. import com.cx.itext.ReplaceRegion;
                  21. import com.itextpdf.awt.geom.Rectangle2D.Float;
                  22. import com.itextpdf.text.pdf.parser.ImageRenderInfo;
                  23. import com.itextpdf.text.pdf.parser.RenderListener;
                  24. import com.itextpdf.text.pdf.parser.TextRenderInfo;
                  25. * pdf渲染监听,当找到渲染的文本时,得到文本的坐标x,y,w,h
                  26. * @user : caoxu-yiyang@qq.com
                  27. * @date : 2016年11月9日
                  28. public class PositionRenderListener implements RenderListener{
                  29. private List<String> findText;
                  30. private float defaultH; ///出现无法取到值的情况,默认为12
                  31. private float fixHeight; //可能出现无法完全覆盖的情况,提供修正的参数,默认为2
                  32. public PositionRenderListener(List<String> findText, float defaultH, float fixHeight) {
                  33. this.findText = findText;
                  34. this.defaultH = defaultH;
                  35. this.fixHeight = fixHeight;
                  36. public PositionRenderListener(List<String> findText) {
                  37. this.findText = findText;
                  38. this.defaultH = 12;
                  39. this.fixHeight = 2;
                  40. @Override
                  41. public void beginTextBlock() {
                  42. @Override
                  43. public void endTextBlock() {
                  44. @Override
                  45. public void renderImage(ImageRenderInfo imageInfo) {
                  46. private Map<String, ReplaceRegion> result = new HashMap<String, ReplaceRegion>();
                  47. @Override
                  48. public void renderText(TextRenderInfo textInfo) {
                  49. String text = textInfo.getText();
                  50. for (String keyWord : findText) {
                  51. if ( null != text && text.equals(keyWord)){
                  52. Float bound = textInfo.getBaseline().getBoundingRectange();
                  53. ReplaceRegion region = new ReplaceRegion(keyWord);
                  54. region.setH(bound.height == 0 ? defaultH : bound.height);
                  55. region.setW(bound.width);
                  56. region.setX(bound.x);
                  57. region.setY(bound.y- this.fixHeight);
                  58. result.put(keyWord, region);
                  59. public Map<String, ReplaceRegion> getResult() {
                  60. for (String key : findText) { //补充没有找到的数据
                  61. if( this.result.get(key) == null){
                  62. this.result.put(key, null);
                  63. return this.result; 我用到的jar包如下:

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