java读PDF表格中的文字,查询到指定文字‘签名’后,向右边的表格内插入本地图片,写详细demo

时间: 2023-05-22 12:07:01 浏览: 50
非常感谢您的提问。以下是一个基于Apache PDFBox的Java代码示例,它可以读取PDF表格中的文字,并在找到指定文字“签名”时,在其右侧插入本地图片。 在本示例中,我们将使用一个名为"test.pdf"的PDF文件。我们将尝试在该文件的第一个页面中查找名为“签名”的单元格,并在单元格的右侧插入本地图像"image.png"。 以下是完整的示例代码: // 导入PDFBox库 import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.table.PDPageContentStreamTableCell; import org.apache.pdfbox.pdmodel.table.PDTable; import org.apache.pdfbox.pdmodel.table.PDTableElement; import org.apache.pdfbox.pdmodel.table.PDTableElementCell; import org.apache.pdfbox.pdmodel.table.PDTableElementRow; import org.apache.pdfbox.pdmodel.table.PDTableFactory; import org.apache.pdfbox.pdmodel.table.PDTableStyle; import org.apache.pdfbox.pdmodel.table.PDTextCell; import org.apache.pdfbox.pdmodel.table.PDTextElement; import org.apache.pdfbox.pdmodel.table.PDTextRow; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.util.Matrix; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class PDFTableImageInsertDemo { public static void main(String[] args) { String pdfFilePath = "test.pdf"; String findText = "签名"; String imageFilePath = "image.png"; try { // 加载PDF文件 PDDocument document = PDDocument.load(new File(pdfFilePath)); PDPage page = document.getPage(0); // 获得页面的宽和高 float pageWidth = page.getMediaBox().getWidth(); float pageHeight = page.getMediaBox().getHeight(); // 获得页面中的表格 PDTable table = PDTableFactory.createTable(getTableContent(page), new PDTableStyle()); // 搜索指定的单元格 PDTableElementRow foundRow = null; PDTableElementCell foundCell = null; boolean found = false; for (int rowIndex = 0; rowIndex < table.getHeaderRowCount(); rowIndex++) { PDTableElementRow row = table.getHeaderRow(rowIndex); for (int cellIndex = 0; cellIndex < row.getCellCount(); cellIndex++) { PDTableElementCell cell = row.getCell(cellIndex); if (cell.containsText() && cell.getText().equals(findText)) { foundRow = row; foundCell = cell; found = true; break; } } if (found) break; } if (found) { // 在发现的单元格右边插入图像 int rowNum = foundRow.getRowIndex(); int cellNum = foundCell.getColumnIndex(); PDTableElementRow imageRow = table.getRow(rowNum); PDTableElementCell imageCell = new PDPageContentStreamTableCell(); imageCell.setColSpan(1); imageCell.setRowSpan(1); float cellWidth = foundCell.getColSpan() * foundCell.getWidth(); float cellLeft = foundCell.getTopLeftX(); float cellTop = imageRow.getTop() - imageRow.getHeight() - 5; // 插入图像 BufferedImage image = ImageIO.read(new File(imageFilePath)); PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, false); contentStream.drawImage( image, cellLeft + cellWidth, cellTop, image.getWidth() / 2, image.getHeight() / 2 ); contentStream.close(); // 输出修改后的表格 try (PDPageContentStream contents = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true)) { Matrix matrix = new Matrix(); matrix.translate(0, pageHeight); matrix.scale(1, -1); contents.transform(matrix); table.draw(contents, 0, 0, pageWidth - 50, pageHeight - 50, true); } } else { System.out.println("无法找到指定的单元格: " + findText); } // 保存修改后的PDF文档 document.save("output.pdf"); document.close(); System.out.println("已成功在指定单元格插入图像。"); } catch (IOException ex) { System.err.println("出现错误: " + ex.getMessage()); } } // 从表格获取数据 private static PDTableElement getTableContent(PDPage page) throws IOException { PDTableElement tableElement = new PDTextRow(); PDFRenderer renderer = new PDFRenderer(page); BufferedImage image = renderer.renderImageWithDPI(72, ImageType.RGB); int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); PDType1Font font = PDType1Font.HELVETICA; int fontSize = 12; int tableTop = 0; int tableLeft = 0; int tableWidth = 0; for (int y = 0; y < imageHeight; y++) { StringBuilder rowText = null; int rowLeft = -1, cellIndex = 0; for (int x = 0; x < imageWidth; x++) { int color = image.getRGB(x, y); int red = (color >> 16) & 0xff; if (red > 200) { if (rowText == null) { rowText = new StringBuilder(); rowLeft = x; } rowText.append((char) color); } else if (rowText != null) { // 新单元格开始 String cellContent = rowText.toString().trim(); PDTextElement cellElement = new PDTextCell(); cellElement.setFont(font); cellElement.setFontSize(fontSize); cellElement.setLineSpacing(1.0f); cellElement.setIndent(5.0f); cellElement.setText(cellContent); PDTableElementCell cell = new PDPageContentStreamTableCell(); cell.setColSpan(1); cell.setRowSpan(1); cell.setElement(cellElement); PDTableElementRow row = tableElement.getLast() != null ? (PDTableElementRow) tableElement.getLast() : null; if (row == null || row.getTop() != tableTop) { row = new PDTextRow(); ((PDTextRow) row).setIndent(0); tableElement.addElement(row); tableTop = row.getTop(); tableLeft = rowLeft; tableWidth = 0; } assert row != null; if (x - rowLeft < tableWidth || cellIndex >= row.getCellCount()) { row.addElement(cell); } else { for (int i = row.getCellCount() - 1; i >= cellIndex; i--) { row.removeElement(i); } row.addElement(cell, cellIndex); } cellIndex++; rowText = null; } } if (rowText != null) { // 新行开始 String rowContent = rowText.toString().trim(); PDTextElement rowElement = new PDTextRow(); rowElement.setFont(font); rowElement.setFontSize(fontSize); rowElement.setLineSpacing(1.0f); rowElement.setIndent(5.0f); rowElement.setText(rowContent); PDTableElementRow row = new PDTextRow(); ((PDTextRow) row).setIndent(0); row.addElement(new PDPageContentStreamTableCell(), cellIndex); row.addElement(new PDPageContentStreamTableCell(), cellIndex + 1); row.setElement(rowElement); tableElement.addElement(row); } } return tableElement; } } 希望这个代码示例对您有所帮助。如果您有任何疑问,请随时告诉我。

相关推荐

最新推荐

recommend-type

BootStrap实现带有增删改查功能的表格(DEMO详解)

主要介绍了BootStrap实现带有增删改查功能的表格,表格封装了3个版本,接下来通过本文给大家展示下样式及代码,对bootstrap增删改查相关知识感兴趣的朋友一起通过本文学习吧
recommend-type

java使用es查询的示例代码

本篇文章主要介绍了java使用es查询的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
recommend-type

js+div实现文字滚动和图片切换效果代码

这里演示js+div文字滚动和图片切换代码,为了演示方便,去掉了图片调用,用数字代替了,用时候再加上就可以了,本效果实现了两种效果,Div切换,TAB切换,和文字滚动,鼠标移上后文字停止滚动,两种功能可任意剥离...
recommend-type

JS实现table表格数据排序功能(可支持动态数据+分页效果)

我写了一个简单的Demo排序. 数据就是字母和数字两组.(汉字需要找到asc码) 原理就是利用数组自带的sort排序,进行表格重组.已在.net mvc 中测试过.支持分页.(申明一点.只对当前页面数据排序 无刷新,对所有页面排序的话...
recommend-type

JAVA实现长连接(含心跳检测Demo)

主要介绍了JAVA实现长连接(含心跳检测Demo),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
recommend-type

RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz

REALTEK 8188FTV 8188eus 8188etv linux驱动程序稳定版本, 支持AP,STA 以及AP+STA 共存模式。 稳定支持linux4.0以上内核。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

爬虫与大数据分析:挖掘数据价值,洞察趋势

![python网站爬虫技术实战](https://img-blog.csdnimg.cn/20181107141901441.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hpaGVsbA==,size_16,color_FFFFFF,t_70) # 1. 爬虫基础与技术** 爬虫,又称网络蜘蛛,是一种自动化的程序,用于从互联网上抓取数据。其工作原理是模拟浏览器行为,通过发送请求并解析响应来获取网页内容。 爬虫技术涉及多种技术,
recommend-type

解释一下下面每句话的含义@RequestMapping(value = "gcGl") public String gcGl(Gcgl gcGl, Model model) { List<Gcgl> list = gcglService.findList(gcGl); if (list!=null&&list.size()>0) { model.addAttribute("gcGl", list.get(0)); }else { model.addAttribute("gcGl", gcGl); } return "modules/tjxx/gc08glForm"; }

这段代码是一个Java方法,用于处理HTTP请求,具体含义如下: - @RequestMapping(value = "gcGl"):这是一个注解,表示该方法会处理名为"gcGl"的请求,即当用户访问该请求时,会调用该方法。 - public String gcGl(Gcgl gcGl, Model model):这是方法的声明,它有两个参数:一个是Gcgl类型的gcGl,另一个是Model类型的model。方法的返回值是一个字符串类型。 - List<Gcgl> list = gcglService.findList(gcGl):这行代码调用了一个名为findList的方法,该方法接受一个
recommend-type

c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf

校园超市商品信息管理系统课程设计旨在帮助学生深入理解程序设计的基础知识,同时锻炼他们的实际操作能力。通过设计和实现一个校园超市商品信息管理系统,学生掌握了如何利用计算机科学与技术知识解决实际问题的能力。在课程设计过程中,学生需要对超市商品和销售员的关系进行有效管理,使系统功能更全面、实用,从而提高用户体验和便利性。 学生在课程设计过程中展现了积极的学习态度和纪律,没有缺勤情况,演示过程流畅且作品具有很强的使用价值。设计报告完整详细,展现了对问题的深入思考和解决能力。在答辩环节中,学生能够自信地回答问题,展示出扎实的专业知识和逻辑思维能力。教师对学生的表现予以肯定,认为学生在课程设计中表现出色,值得称赞。 整个课程设计过程包括平时成绩、报告成绩和演示与答辩成绩三个部分,其中平时表现占比20%,报告成绩占比40%,演示与答辩成绩占比40%。通过这三个部分的综合评定,最终为学生总成绩提供参考。总评分以百分制计算,全面评估学生在课程设计中的各项表现,最终为学生提供综合评价和反馈意见。 通过校园超市商品信息管理系统课程设计,学生不仅提升了对程序设计基础知识的理解与应用能力,同时也增强了团队协作和沟通能力。这一过程旨在培养学生综合运用技术解决问题的能力,为其未来的专业发展打下坚实基础。学生在进行校园超市商品信息管理系统课程设计过程中,不仅获得了理论知识的提升,同时也锻炼了实践能力和创新思维,为其未来的职业发展奠定了坚实基础。 校园超市商品信息管理系统课程设计的目的在于促进学生对程序设计基础知识的深入理解与掌握,同时培养学生解决实际问题的能力。通过对系统功能和用户需求的全面考量,学生设计了一个实用、高效的校园超市商品信息管理系统,为用户提供了更便捷、更高效的管理和使用体验。 综上所述,校园超市商品信息管理系统课程设计是一项旨在提升学生综合能力和实践技能的重要教学活动。通过此次设计,学生不仅深化了对程序设计基础知识的理解,还培养了解决实际问题的能力和团队合作精神。这一过程将为学生未来的专业发展提供坚实基础,使其在实际工作中能够胜任更多挑战。