java實(shí)現(xiàn)查找PDF關(guān)鍵字所在頁碼及其坐標(biāo)
1、因?yàn)樽罱羞@方面的需求,用過之后記錄一下。
2、此功能跟PDF中Ctrl+F性質(zhì)一樣,如果PDF中為圖片形式的不支持定位到關(guān)鍵字。
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.定義一個(gè)byte數(shù)組,長度為文件的長度 byte[] pdfData = new byte[(int) pdfFile.length()]; //3.IO流讀取文件內(nèi)容到byte數(shù)組 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.指定關(guān)鍵字 String keyword = "消失的太陽:"; //5.調(diào)用方法,給定關(guān)鍵字和文件 List<float[]> positions = findKeywordPostions(pdfData, keyword); //6.返回值類型是 List<float[]> 每個(gè)list元素代表一個(gè)匹配的位置,分別為 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文件轉(zhuǎn)化的byte數(shù)組 * @param keyword 關(guān)鍵字 * @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(); //這兩個(gè)是關(guān)鍵字在所在頁面的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 + "]"; } } }
總結(jié)
以上所述是小編給大家介紹的java實(shí)現(xiàn)查找PDF關(guān)鍵字所在頁碼及其坐標(biāo),希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
解決springboot 實(shí)體類String轉(zhuǎn)Date類型的坑
這篇文章主要介紹了解決springboot 實(shí)體類String轉(zhuǎn)Date類型的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10java配置多個(gè)過濾器優(yōu)先級(jí)以及幾個(gè)常用過濾器操作
這篇文章主要介紹了java配置多個(gè)過濾器優(yōu)先級(jí)以及幾個(gè)常用過濾器的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07java編程下字符串的16位,32位md5加密實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猨ava編程下字符串的16位,32位md5加密實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09application.yml文件中如何開啟mybatis自動(dòng)駝峰映射
這篇文章主要介紹了application.yml文件中開啟mybatis自動(dòng)駝峰映射的方法,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08在CentOS系統(tǒng)上安裝Java?JDK?8簡單步驟
最近購買一臺(tái)新的云服務(wù)器,用于開發(fā)學(xué)習(xí)使用,因此需要安裝很多的組件,下面這篇文章主要給大家介紹了關(guān)于在CentOS系統(tǒng)上安裝Java?JDK8的簡單步驟,需要的朋友可以參考下2023-12-12Springboot+MyBatist實(shí)現(xiàn)前后臺(tái)交互登陸功能方式
這篇文章主要介紹了Springboot+MyBatist實(shí)現(xiàn)前后臺(tái)交互登陸功能方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Springboot基于websocket實(shí)現(xiàn)簡單在線聊天功能
這篇文章主要介紹了Springboot基于websocket實(shí)現(xiàn)簡單在線聊天功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06