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 + "]";
}
}
原文地址:https://www.cnblogs.com/wangwiz/p/9172759.html