java实现查找PDF关键字所在页码及其坐标

1、因为最近有这方面的需求,用过之后记录一下。

2、此功能跟PDF中Ctrl+F性质一样,如果PDF中为图片形式的不支持定位到关键字。

import com.itextpdf.awt.geom.Rectangle2D.Float;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
 * 消失的太阳
 */
public class MyTest {
 public static void main(String[] args) throws IOException {
  //1.给定文件
  File pdfFile = new File("D://test.pdf");
  //2.定义一个byte数组,长度为文件的长度
  byte[] pdfData = new byte[(int) pdfFile.length()];
  //3.IO流读取文件内容到byte数组
  FileInputStream inputStream = null;
  try {
   inputStream = new FileInputStream(pdfFile);
   inputStream.read(pdfData);
  } catch (IOException e) {
   throw e;
  } finally {
   if (inputStream != null) {
    try {
     inputStream.close();
    } catch (IOException e) {
    }
   }
  }
  //4.指定关键字
  String keyword = "消失的太阳:";
  //5.调用方法,给定关键字和文件
  List<float[]> positions = findKeywordPostions(pdfData, keyword);
  //6.返回值类型是 List<float[]> 每个list元素代表一个匹配的位置,分别为 float[0]所在页码 float[1]所在x轴 float[2]所在y轴
  System.out.println("total:" + positions.size());
  if (positions != null && positions.size() > 0) {
   for (float[] position : positions) {
    System.out.print("pageNum: " + (int) position[0]);
    System.out.print("\tx: " + position[1]);
    System.out.println("\ty: " + position[2]);
   }
  }
 }
 /**
  * findKeywordPostions
  * @param pdfData  通过IO流 PDF文件转化的byte数组
  * @param keyword  关键字
  * @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y
  * @throws IOException
  */
 public static List<float[]> findKeywordPostions(byte[] pdfData, String keyword) throws IOException {
  List<float[]> result = new ArrayList<>();
  List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);
  for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {
   List<float[]> charPositions = findPositions(keyword, pdfPageContentPosition);
   if (charPositions == null || charPositions.size() < 1) {
    continue;
   }
   result.addAll(charPositions);
  }
  return result;
 }
 private static List<PdfPageContentPositions> getPdfContentPostionsList(byte[] pdfData) throws IOException {
  PdfReader reader = new PdfReader(pdfData);
  List<PdfPageContentPositions> result = new ArrayList<>();
  int pages = reader.getNumberOfPages();
  for (int pageNum = 1; pageNum <= pages; pageNum++) {
   float width = reader.getPageSize(pageNum).getWidth();
   float height = reader.getPageSize(pageNum).getHeight();
   PdfRenderListener pdfRenderListener = new PdfRenderListener(pageNum, width, height);
   //解析pdf,定位位置
   PdfContentStreamProcessor processor = new PdfContentStreamProcessor(pdfRenderListener);
   PdfDictionary pageDic = reader.getPageN(pageNum);
   PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
   try {
    processor.processContent(ContentByteUtils.getContentBytesForPage(reader, pageNum), resourcesDic);
   } catch (IOException e) {
    reader.close();
    throw e;
   }
   String content = pdfRenderListener.getContent();
   List<CharPosition> charPositions = pdfRenderListener.getcharPositions();
   List<float[]> positionsList = new ArrayList<>();
   for (CharPosition charPosition : charPositions) {
    float[] positions = new float[]{charPosition.getPageNum(), charPosition.getX(), charPosition.getY()};
    positionsList.add(positions);
   }
   PdfPageContentPositions pdfPageContentPositions = new PdfPageContentPositions();
   pdfPageContentPositions.setContent(content);
   pdfPageContentPositions.setPostions(positionsList);
   result.add(pdfPageContentPositions);
  }
  reader.close();
  return result;
 }
 private static List<float[]> findPositions(String keyword, PdfPageContentPositions pdfPageContentPositions) {
  List<float[]> result = new ArrayList<>();
  String content = pdfPageContentPositions.getContent();
  List<float[]> charPositions = pdfPageContentPositions.getPositions();
  for (int pos = 0; pos < content.length(); ) {
   int positionIndex = content.indexOf(keyword, pos);
   if (positionIndex == -1) {
    break;
   }
   float[] postions = charPositions.get(positionIndex);
   result.add(postions);
   pos = positionIndex + 1;
  }
  return result;
 }
 private static class PdfPageContentPositions {
  private String content;
  private List<float[]> positions;
  public String getContent() {
   return content;
  }
  public void setContent(String content) {
   this.content = content;
  }
  public List<float[]> getPositions() {
   return positions;
  }
  public void setPostions(List<float[]> positions) {
   this.positions = positions;
  }
 }
 private static class PdfRenderListener implements RenderListener {
  private int pageNum;
  private float pageWidth;
  private float pageHeight;
  private StringBuilder contentBuilder = new StringBuilder();
  private List<CharPosition> charPositions = new ArrayList<>();
  public PdfRenderListener(int pageNum, float pageWidth, float pageHeight) {
   this.pageNum = pageNum;
   this.pageWidth = pageWidth;
   this.pageHeight = pageHeight;
  }
  public void beginTextBlock() {
  }
  public void renderText(TextRenderInfo renderInfo) {
   List<TextRenderInfo> characterRenderInfos = renderInfo.getCharacterRenderInfos();
   for (TextRenderInfo textRenderInfo : characterRenderInfos) {
    String word = textRenderInfo.getText();
    if (word.length() > 1) {
     word = word.substring(word.length() - 1, word.length());
    }
    Float rectangle = textRenderInfo.getAscentLine().getBoundingRectange();
    float x = (float)rectangle.getX();
    float y = (float)rectangle.getY();
//    float x = (float)rectangle.getCenterX();
//    float y = (float)rectangle.getCenterY();
//    double x = rectangle.getMinX();
//    double y = rectangle.getMaxY();
    //这两个是关键字在所在页面的XY轴的百分比
    float xPercent = Math.round(x / pageWidth * 10000) / 10000f;
    float yPercent = Math.round((1 - y / pageHeight) * 10000) / 10000f;
//    CharPosition charPosition = new CharPosition(pageNum, xPercent, yPercent);
    CharPosition charPosition = new CharPosition(pageNum, (float)x, (float)y);
    charPositions.add(charPosition);
    contentBuilder.append(word);
   }
  }
  public void endTextBlock() {
  }
  public void renderImage(ImageRenderInfo renderInfo) {
  }
  public String getContent() {
   return contentBuilder.toString();
  }
  public List<CharPosition> getcharPositions() {
   return charPositions;
  }
 }
 private static class CharPosition {
  private int pageNum = 0;
  private float x = 0;
  private float y = 0;
  public CharPosition(int pageNum, float x, float y) {
   this.pageNum = pageNum;
   this.x = x;
   this.y = y;
  }
  public int getPageNum() {
   return pageNum;
  }
  public float getX() {
   return x;
  }
  public float getY() {
   return y;
  }
  @Override
  public String toString() {
   return "[pageNum=" + this.pageNum + ",x=" + this.x + ",y=" + this.y + "]";
  }
 }
}

总结

以上所述是小编给大家介绍的java实现查找PDF关键字所在页码及其坐标,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Java开源工具iText生成PDF简单实例

    iText下载页面: http://sourceforge.net/projects/itext/files/ 1.创建简单的PDF文件 package console.pdf; import java.io.FileNotFoundException; import java.io.FileOutputStream; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com

  • Java实现Html转Pdf的方法

    本文实例讲述了Java实现Html转Pdf的方法.分享给大家供大家参考.具体如下: package test; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import org.xhtmlrenderer.pdf.ITextFontResolver; import org.xhtmlrenderer.pdf.ITextRenderer; import com.lowagie.

  • java中输出pdf文件代码分享

    package snake; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowag

  • java实现PPT转化为PDF

    JACOB的方法,足可以解决这个问题,但是我既然以前曾经做过报表,就想尝试不同的方法. JACOB是一座连接JAVA和微软的桥,所有的解析由微软解析.POI是没有微软解析的那么原汁原味的,所以如果要求高的话,还是使用JACOB. 大致思路很简单,将PPT先转化为图片,然后将图片写入PDF.转化图片是用POI,操作PDF使用ITEX.不过这个方法的BUG就是转化图片的POI效果不是很好. 导入的包分别是:itextpdf-5.1.3.jar,poi-3.8-20120326.jar,poi-scr

  • java实现PDF转图片的方法

    本文实例为大家分享了java实现PDF转图片的具体代码,供大家参考,具体内容如下 1.首先利用maven引入所需jar包 <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>fontbox</artifactId> <version>2.0.1</version> </dependency> <dependency> <g

  • Java将图片组合成PDF文件的方法

    本文实例为大家分享了Java将图片组合成PDF文件的具体代码,供大家参考,具体内容如下 程序界面图: 代码清单: package 将图片组合成PDF文件; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileFilter; import java.io.FileOutputStream; import java.io.IOE

  • java原装代码完成pdf在线预览和pdf打印及下载

    前提准备: 1. 项目中至少需要引入的jar包,注意版本: a) core-renderer.jar b) freemarker-2.3.16.jar c) iText-2.0.8.jar d) iTextAsian.jar 上代码: 注释: 此类为自定义的Tag类的基类,在action中怎么放的数据,在ftl中就怎么取数据,简洁明了.  1. 自定义Tag类的基类 /** * 通用的生成pdf预览和生成打印的html文件 * * @author xg君 * */ public abstract

  • Java生成PDF文件的实例代码

    复制代码 代码如下: package com.qhdstar.java.pdf; import java.awt.Color;import java.io.FileOutputStream; import com.lowagie.text.Chapter;import com.lowagie.text.Document;import com.lowagie.text.Font;import com.lowagie.text.FontFactory;import com.lowagie.text.

  • Java查找并高亮PDF文本过程解析

    本文将介绍如何通过Java程序来查找并高亮PDF中的文本. 使用工具:Free Spire.PDF for Java(免费版) Jar文件获取及导入: 方法1:官网下载Jar文件包.下载后,解压,并将lib文件夹下的Spire.Pdf.jar文件导入到java程序.参考如下导入效果: 方法2:可通过maven仓库导入. Java代码示例 import com.spire.pdf.*; import com.spire.pdf.general.find.PdfTextFind; import ja

  • java实现查找PDF关键字所在页码及其坐标

    1.因为最近有这方面的需求,用过之后记录一下. 2.此功能跟PDF中Ctrl+F性质一样,如果PDF中为图片形式的不支持定位到关键字. import com.itextpdf.awt.geom.Rectangle2D.Float; import com.itextpdf.text.pdf.PdfDictionary; import com.itextpdf.text.pdf.PdfName; import com.itextpdf.text.pdf.PdfReader; import com.i

  • Java实现查找算法的示例代码(二分查找、插值查找、斐波那契查找)

    目录 1.查找概述 2.顺序查找 3.二分查找 3.1 二分查找概述 3.2 二分查找实现 4.插值查找 4.1 插值查找概述 4.2 插值查找实现 5.斐波那契查找 5.1 斐波那契查找概述 5.2 斐波那契查找实现 5.3 总结 1.查找概述 查找表: 所有需要被查的数据所在的集合,我们给它一个统称叫查找表.查找表(Search Table)是由同一类型的数据元素(或记录)构成的集合. 查找(Searching): 根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录).

  • java实现在pdf模板的指定位置插入图片

    本文实例为大家分享了java在pdf模板的指定位置插入图片的具体代码,供大家参考,具体内容如下 java操作pdf有个非常好用的库itextpdf,maven: <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.6</version> </dependency> <!--

  • Python利用PyPDF2库获取PDF文件总页码实例

    Python中可以利用PyPDF2库来获取该pdf文件的总页码,可以根据下面的方法一步步进行下去: 1.首先,要安装PyPDF2库,利用以下命令即可: pip install PyPDF2 2.接着,就是直接编写代码了,其中我新建了一个py文件,名为file_utils.py,代码如下: from PyPDF2 import PdfFileReader def get_num_pages(file_path): """ 获取文件总页码 :param file_path: 文件

  • Java 二分查找算法的实现

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小 于该中点元素,则将待查序列缩小为左半部分,否则为右半部分.通过一次比较,将查找区间缩小一半. 折半查找是一种高效的查找方法.它可以明显减少比较次数,提高查找效率.但是,折半查找的先决条件是查找表中的数据元素必须有序. 折半查找法的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删

  • Java 二分查找的实现及图例解析

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元素,则将待查序列缩小为左半部分,否则为右半部分.通过一次比较,将查找区间缩小一半. 折半查找是一种高效的查找方法.它可以明显减少比较次数,提高查找效率.但是,折半查找的先决条件是查找表中的数据元素必须有序. 折半查找法的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除

  • java 后端生成pdf模板合并单元格表格的案例

    这里只放部分片段的代码 java中使用二维数组生成表格非常方便,但是每一维的数组都需要排好序,而且,在java中所谓的二维数组,三维数组等,其实都是多个一维数组组成的 /** * 添加子女教育规划表. * @param name 子女姓名 * @param educationItems 某个孩子的教育规划的二维数组,每列依次是:学程阶段.年数.费用支出(元)/年.年增长率 * @param spacing * @throws DocumentException * @throws IOExcep

  • binarySearch在java的查找实例用法

    在java数组中,查找数组元素是比较基础的操作了,arrays类的binarySearch就是专门实现指定元素的.同时它也属于我们常说的二分法.所以作用的范围是排序过的数组.下面我们就binarySearch的概念.使用注意进行说明,同时分出它的两种返回值情况,最后进行查找的实例分享. 1.概念 通过二分法在已经排好序的数组中查找指定的元素,并返回该元素的下标. 2.使用注意 此法为二分搜索法,故查询前需要用sort()方法将数组排序,如果数组没有排序,则结果是不确定的.如果数组中含有多个指定值

  • Java预览PDF时的文件名称问题及解决

    目录 Java预览PDF时的文件名称 问题场景 解决思路 解决方案 预览pdf时中文乱码 第一步 第二步 Java预览PDF时的文件名称 问题场景 今天在做新项目的时候,测试提交过来一个bug:在谷歌浏览器上预览一些客户上传的pdf文件时,发现浏览器的标签上展示的要么不是我们看到的文件名,要么就直接是方法名,看起来不太合适,让我想想办法优化优化. 刚开始看到这个问题的时候确实很头疼,因为之前尝试过去解决这个问题,但是当时因为一些其他的原因,没有仔细的去思考这些个问题,这会做新项目刚好有时间去琢磨

  • 利用Java实现在PDF中添加工具提示

    目录 导入jar包 添加工具提示ToolTip 本文,将介绍如何通过Java后端程序代码在PDF中创建工具提示.添加工具提示后,当鼠标悬停在页面上的元素时,将显示工具提示内容. 导入jar包 本次程序中使用的是 Free Spire.PDF for Java,具体导入jar文件的方法参考如下内容. 两种方法可导入jar到程序: 方法1. 通过Maven仓库下载导入.在pom.xml配置: <repositories> <repository> <id>com.e-ice

随机推荐