• java使用itex读取pdf,并搜索关键字,为其盖章


    导读:近期要做一个根据关键字定位pdf的盖章位置的相关需求,其中关键字可配置多个(包含pdf文档中可能不存在的关键字),当页面显示盖章完成时,打开pdf显示已经损坏。 
    排查后发现,当itext搜索的关键字在pdf文档中不存在时,就已经将结果返回到前台界面,这时itex读取的流还未关闭,导致pdf读取未结束,pdf文档才被损坏。 
    下面是读取pdf的操作,记录一下: 
    所需包: itext-2.06.jar itext-asian,jar itextpdf-5.4.0.jar

     /****搜索关键字操作:****/
       /*sourcePDF: pdf的文档路径
       splitParentkeyValues[i]:关键字,其中对关键字进行特殊符号的过滤,不然会导致后面的匹配结果有误。*/
       matches = MatchItemUtil.matchPage(sourcePDF, splitParentkeyValues[i]);
     
     /*找出关键字后,将要盖章的图片准确定位到关键字周围,也可以采用坐标的方式**/
     MatchItem matchItem  = new MatchItem();
     int pageNum = matches.get(j).getPageNum();
     float pageWidth = reader.getPageSize(pageNum).getWidth();
     float pageHeight = reader.getPageSize(pageNum).getHeight();
     matchItem.setX(matches.get(j).getX()-splitParentkeyValues.length * 20);
     matchItem.setY(matches.get(j).getY() - 150 / 1.527731f);
     img.setAbsolutePosition(matchItem.getX(), matchItem.getY());// 位置
     PdfContentByte over = stamp.getOverContent(pageNum);
     over.addImage(img);

    1. //根据关键字和pdf路径,全文搜索关键字 

     /**
     
     查找所有
     @param fileName 文件路径
     @param keyword 关键词
     @return
     @throws Exception 
     */
     public static List matchPage(String fileName,String keyword) throws Exception { 
     List items = new ArrayList(); 
     PdfReader reader = new PdfReader(fileName); 
     int pageSize = reader.getNumberOfPages(); 
     for(int page = 1;page <= pageSize;page++){ 
     items.addAll(matchPage(reader,page,keyword)); 
     } 
     return items; 
     }

    2. 根据关键字、文档路径、pdf页数寻找特定的文件内容

     /**
     
     在文件中寻找特定的文字内容
     @param reader
     @param pageNumber
     @param keyword
     @return
     @throws Exception 
     */ 
     public static List matchPage(PdfReader reader, Integer pageNumber,String keyword) throws Exception { 
     KeyWordPositionListener renderListener = new KeyWordPositionListener(); 
     renderListener.setKeyword(keyword); 
     PdfReaderContentParser parse = new PdfReaderContentParser(reader); 
     Rectangle rectangle = reader.getPageSize(pageNumber); 
     renderListener.setPageNumber(pageNumber); 
     renderListener.setCurPageSize(rectangle); 
     parse.processContent(pageNumber, renderListener); 
     return findKeywordItems(renderListener,keyword); 
     }

    3. 找到匹配的关键词块 

    /**
    
    找到匹配的关键词块
    @param renderListener
    @param keyword
    @return 
    */ 
    public static List findKeywordItems(KeyWordPositionListener renderListener,String keyword){ 
    //先判断本页中是否存在关键词 
    List allItems = renderListener.getAllItems();//所有块LIST 
    StringBuffer sbtemp = new StringBuffer(“”); 
    for(MatchItem item : allItems){//将一页中所有的块内容连接起来组成一个字符串。 
    sbtemp.append(item.getContent()); 
    } 
    if(sbtemp.toString().indexOf(keyword) == -1){//一页组成的字符串没有关键词,直接return 
    return renderListener.getMatches(); 
    } 
    //第一种情况:关键词与块内容完全匹配的项 
    List matches = renderListener.getMatches(); 
    //第二种情况:多个块内容拼成一个关键词,则一个一个来匹配,组装成一个关键词 
    sbtemp = new StringBuffer(“”); 
    List tempItems = new ArrayList(); 
    for(MatchItem item : allItems){ 
    //1,关键词中存在某块 2,拼装的连续的块=关键词 3,避开某个块完全匹配关键词 
    //关键词 中国移动 而块为 中 ,国,移动 
    //关键词 中华人民 而块为中,华人民共和国 这种情况解决不了,也不允许存在 
    if(keyword.indexOf(item.getContent()) != -1 && !keyword.equals(item.getContent())){ 
    tempItems.add(item); 
    sbtemp.append(item.getContent()); 
    if(keyword.indexOf(sbtemp.toString()) == -1){//如果暂存的字符串和关键词 不再匹配时 
    sbtemp = new StringBuffer(item.getContent()); 
    tempItems.clear(); 
    tempItems.add(item); 
    } 
    if(sbtemp.toString().equalsIgnoreCase(keyword)){//暂存的字符串正好匹配到关键词时 
    MatchItem tmpitem = getRightItem(tempItems, keyword); 
    if(tmpitem != null){ 
    matches.add(tmpitem);//得到匹配的项 
    } 
    sbtemp = new StringBuffer(“”);//清空暂存的字符串 
    tempItems.clear();//清空暂存的LIST 
    continue;//继续查找 
    } 
    }else{//如果找不到则清空 
    sbtemp = new StringBuffer(“”); 
    tempItems.clear(); 
    } 
    } 
    //第三种情况:关键词存在块中 
    for(MatchItem item : allItems){ 
    if(item.getContent().indexOf(keyword) != -1 && !keyword.equals(item.getContent())){ 
    matches.add(item); 
    } 
    } 
    return matches; 
    }

    public static MatchItem getRightItem(List<MatchItem> tempItems,String keyword){ 
    for(MatchItem item:tempItems){ 
        if(keyword.indexOf(item.getContent()) != -1 && !keyword.equals(item.getContent())){ 
          return item; 
        } 
      } return null; 
    }
    
    
    4. KeyWordPositionListener用来匹配pdf的关键词
    import java.util.ArrayList; 
    import java.util.List;
    
    import org.apache.log4j.Logger; 
    import org.drools.util.StringUtils;
    
    import com.itextpdf.awt.geom.Rectangle2D; 
    import com.itextpdf.text.Rectangle; 
    import com.itextpdf.text.pdf.parser.ImageRenderInfo; 
    import com.itextpdf.text.pdf.parser.RenderListener; 
    import com.itextpdf.text.pdf.parser.TextRenderInfo; 
    public class KeyWordPositionListener implements RenderListener { 
    private static Logger logger = Logger.getLogger(KeyWordPositionListener.class);
    private List<MatchItem> matches = new ArrayList<MatchItem>();
    private List<MatchItem> allItems = new ArrayList<MatchItem>();
    private Rectangle curPageSize;
    
    /**
     * 匹配的关键字
     */
    private String keyword;
    /**
     * 匹配的当前页
     */
    private Integer pageNumber;
    
    public void beginTextBlock() {
        //do nothing
    }
    
    public void renderText(TextRenderInfo renderInfo) {
        String content = renderInfo.getText();
        content = content.replace("<", "").replace("《", "").replace("(", "").replace("(", "").replace(""", "").replace("'", "")
                         .replace(">", "").replace("》", "").replace(")", "").replace(")", "").replace("、", "").replace(".", "")
                         .replace(":", "").replace(":", "").replace(" ", "");
        Rectangle2D.Float textRectangle = renderInfo.getDescentLine().getBoundingRectange();
        MatchItem item = new MatchItem();
        item.setContent(content);
        item.setPageNum(pageNumber);
        item.setPageWidth(curPageSize.getWidth());
        item.setPageHeight(curPageSize.getHeight());
        item.setX((float)textRectangle.getX());
        item.setY((float)textRectangle.getY());
        if(!StringUtils.isEmpty(content)){
            if(content.equalsIgnoreCase(keyword)) {
                matches.add(item);
            }           
        }else{
            item.setContent("空字符串");
        }
        allItems.add(item);//先保存所有的项
    }
    
    public void endTextBlock() {
        //do nothing
    }
    
    public void renderImage(ImageRenderInfo renderInfo) {
        //do nothing
    }
    
    /**
     * 设置需要匹配的当前页
     * @param pageNumber
     */
    public void setPageNumber(Integer pageNumber) {
        this.pageNumber = pageNumber;
    }
    
    /**
     * 设置需要匹配的关键字,忽略大小写
     * @param keyword
     */
    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }
    
    /**
     * 返回匹配的结果列表
     * @return
     */
    public List<MatchItem> getMatches() {
        return matches;
    }
    
    void setCurPageSize(Rectangle rect) {
        this.curPageSize = rect;
    }
    
    public List<MatchItem> getAllItems() {
        return allItems;
    }
    
    public void setAllItems(List<MatchItem> allItems) {
        this.allItems = allItems;
    }
    }

    5. 用来保存关键字新建的对象 

    public class MatchItem { 
    private Integer pageNum; 
    private Float x; 
    private Float y; 
    private Float pageWidth; 
    private Float pageHeight; 
    private String content;
    public Integer getPageNum() {
        return pageNum;
    }
    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }
    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 getPageWidth() {
        return pageWidth;
    }
    public void setPageWidth(Float pageWidth) {
        this.pageWidth = pageWidth;
    }
    public Float getPageHeight() {
        return pageHeight;
    }
    public void setPageHeight(Float pageHeight) {
        this.pageHeight = pageHeight;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    
    public String toString() {
        return "MatchItem [pageNum=" + pageNum + ", x=" + x + ", y=" + y
                + ", pageWidth=" + pageWidth + ", pageHeight=" + pageHeight
                + ", content=" + content + "]";
    }
    }
  • 相关阅读:
    测试工程师入门要了解什么?(四)
    测试工程师入门要了解什么?(三)
    测试工程师入门要了解什么?(二)
    测试工程师入门要了解什么?(一)
    测试工程师专业术语
    测试场景标准库
    猜数字
    遍历
    python基础
    python class1
  • 原文地址:https://www.cnblogs.com/wangwiz/p/9172759.html
Copyright © 2020-2023  润新知