java poi 读取 word图片_Java Poi 根据文字内容 插入 word 图片-Go语言中文社区

本文介绍了如何使用Java POI库智能识别并替换Word文档中特定文字为对应图片。通过遍历Word表格,寻找指定标识符,然后读取图片并插入到Word相应位置,清除原始文字。提供了完整的Java代码示例,适用于复杂场景。
摘要由CSDN通过智能技术生成

需求描述

如下图,我需要在word里根据一个图片的名字,将名字替换成该图片(公章)

223d863487e88f6fe72ef7d328a68b2e.png

思路:

用POI遍历每一个表格里的每一行的每一个单元格,如果遇到我自己定义的"&章",则获取后面的图片的名字,然后利用POI的XWPFRun.addPicture(url,像素…)方法将图片添加到word里,然后将原有的文字清除掉。

注意:图片要放在表格的单元格里,最后单元格里的文本会被清除掉,只留下图片

简单生成图片和文字的代码:

注: 我的代码比较复杂,因为需求很复杂,如果你只需要简单生成下图片,可以参考这个

参考:https://stackoverflow.com/questions/26764889/how-to-insert-a-image-in-word-document-with-apache-poi

XWPFDocument doc = new XWPFDocument();

XWPFParagraph title = doc.createParagraph();

XWPFRun run = title.createRun();

run.setText("Fig.1 A Natural Scene");

run.setBold(true);

title.setAlignment(ParagraphAlignment.CENTER);

String imgFile = "encabezado.jpg"

FileInputStream is = new FileInputStream(imgFile);

run.addBreak();

run.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels

is.close();

FileOutputStream fos = new FileOutputStream("test4.docx");

doc.write(fos);

fos.close();

详细代码(原创):

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

import org.apache.poi.util.Units;

import org.apache.poi.xwpf.usermodel.XWPFDocument;

import org.apache.poi.xwpf.usermodel.XWPFParagraph;

import org.apache.poi.xwpf.usermodel.XWPFRun;

import org.apache.poi.xwpf.usermodel.XWPFTable;

import org.apache.poi.xwpf.usermodel.XWPFTableCell;

import org.apache.poi.xwpf.usermodel.XWPFTableRow;

public class blog {

public static void main(String[] args) throws Exception {

//测试添加图片

String sourceFile="D:/测试模板.docx";

String targetFile="D:/test.docx";

addStampImage(sourceFile, targetFile);

}

public static void addStampImage(String sourceFile, String targetFile) {

XWPFDocument doc;

try {

doc = new XWPFDocument(new FileInputStream(sourceFile));

for(XWPFTable table : doc.getTables()) {

for(XWPFTableRow row : table.getRows()) {

for(XWPFTableCell cell : row.getTableCells()) {//遍历每一个单元格

if(cell.getText().contains("&章")) {//如果遇到"&章"则进行替换

try {

insertCellStamp(cell);//给带有要盖章字样的单元格 加上章的图片

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

}

FileOutputStream fos = new FileOutputStream(targetFile);

doc.write(fos);

fos.close();

doc.write(new FileOutputStream(targetFile));

} catch (Exception e) {

e.printStackTrace();

}

}

private static void insertCellStamp(XWPFTableCell cell) throws InvalidFormatException, IOException {//给带有要盖章字样的单元格 加上章的图片

List stamps = new ArrayList<>();//存放要加入的图片

int stampOrder = 0;//图片的序号,从0开始

//获取需要的图片,

for(XWPFParagraph para :cell.getParagraphs()) {

String paraText = para.getText();//从段落中获取要盖的章的名称

//System.out.println("para.getText():" + paraText);

if(paraText != null) {

String[] split = para.getText().split(" ");

for(String s : split) {

s = s.trim();

if(!s.isEmpty() ) {

stamps.add(s.replace("&章", ""));//如:&章公章01.png,去掉标识符&章,只留下章的名字

}

}

}

}

String basedir = "E:";

for(XWPFParagraph para :cell.getParagraphs()) {

for (XWPFRun run : para.getRuns()) {

run.setText("", 0);//清空所有文字

}

//for (int i =para.getRuns().size()-1 ; i>=0; i--) {

//XWPFRun run = para.getRuns().get(i);

//System.out.println("清空所有文字后:run.getText(0): " + run.getText(0));

//}

//插入图片

for(int i = 0; i

try {

XWPFRun run = para.getRuns().get(i);

String imgFile = basedir + "/公章管理/" + stamps.get(stampOrder++);

System.out.println("插入盖章图片:" + imgFile);

FileInputStream is = new FileInputStream(imgFile);

run.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(100), Units.toEMU(100)); // 100x100 pixels

is.close();

run.setText(" ",0);

} catch (Exception e) {

System.out.println("Error: ======== 插入单个公章图片时出错了:可能是图片路径不存在。不影响主流程");

e.printStackTrace();

}

}

}

}

}

最后样子:涉及保密就加了马赛克~

e463653baeb72580ca1de31246325b8a.png

备注:有位朋友说他运行到doc = new XWPFDocument(new FileInputStream(sourceFile));这行时就直接报错:No valid entries or contents found, this is not a valid OOXML (Office Open XML) file报这个错,我和他一起尝试找了下原因,最后也是没找到原因不了了之了。

这段代码已经上线使用了,我这边需求比较复杂,坑也很多,所以建议大家如果需求简单的话就直接参考stackoverflow的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值