Java 替换word文档文字,指定位置插入图片

时间:2022-01-17 05:00:26

先说下 需要的依赖包

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-excelant</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.8</version>
</dependency>
<!-- 生成图片-->
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.19</version>
</dependency>
<dependency>
<!--支持插入图片-->
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>3.3.1</version>
</dependency>

 

示例,下图

 

Java 替换word文档文字,指定位置插入图片

 如上图,需要替换的字符串地方“$1”为“1231”,在指定位置插入书签,并命名“test”    ,插入的图片如下

Java 替换word文档文字,指定位置插入图片

 

本人也没太过多去研究,亲测通过有效,在这分享下

1.demo

import java.awt.Font;
  import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.imageio.ImageIO;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.docx4j.TraversalUtil;

import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.finders.RangeFinder;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.Body;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.CTBookmark;
import org.docx4j.wml.Color;
import org.docx4j.wml.Document;
import org.docx4j.wml.Drawing;
import org.docx4j.wml.HpsMeasure;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.RPr;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.general.DefaultPieDataset;

import com.google.common.collect.Maps;
public class ExportBgServiceImpl {
public static void main(String[] args) throws Exception {
Map
<String, String> map = Maps.newHashMap();
map.put(
"$1", "1231");
XWPFDocument document
= new XWPFDocument(POIXMLDocument.openPackage("D:\\tp\\test.docx"));
Iterator
<XWPFParagraph> itPara = document.getParagraphsIterator();
while (itPara.hasNext()) {
XWPFParagraph paragraph
= (XWPFParagraph) itPara.next();
List
<XWPFRun> runs = paragraph.getRuns();
for (int i = 0; i < runs.size(); i++) {
String oneparaString
= runs.get(i).getText(runs.get(i).getTextPosition()).trim();
for (Map.Entry<String, String> entry : map.entrySet()) {
if (oneparaString.equals(entry.getKey())) {
oneparaString
= oneparaString.replace(entry.getKey(), entry.getValue());
}

}
runs.get(i).setText(oneparaString,
0);
}
}
FileOutputStream outStream
= null;
outStream
= new FileOutputStream("D:\\tp\\test1.docx");
document.write(outStream);
outStream.close();
//-----------------------------------这块为生成图片 和 插入图片
DefaultPieDataset dataset
= new DefaultPieDataset();
dataset.setValue(
"修改类", 1);
dataset.setValue(
"提示类", 1);
dataset.setValue(
"校验不通过", 3);
dataset.setValue(
"正常类", 3);
JFreeChart chart
= ChartFactory.createPieChart3D(null, dataset, true, false, false);
chart.getLegend().setItemFont(
new Font("黑体", Font.BOLD, 15)); // 设置图例类别字体
// TextTitle title = new TextTitle(titleString);
// title.setFont(new Font("黑体", Font.ITALIC, 20));//设置标题字体
// chart.setTitle(title);
PiePlot piePlot = (PiePlot) chart.getPlot();
DecimalFormat df
= new DecimalFormat("0.00%");
NumberFormat nf
= NumberFormat.getInstance();
StandardPieSectionLabelGenerator generator
= new StandardPieSectionLabelGenerator("{0} {2}", nf, df);// 获得StandardPieSectionLabelGenerator对象,生成的格式,
// {0}表示section名,{1}表示section的值,{2}表示百分比。可以自定义
piePlot.setLabelGenerator(generator);// 设置百分比
piePlot.setLabelFont(new Font("黑体", Font.ITALIC, 15));// 设置饼图中类别字体

piePlot.setNoDataMessage(
"此时并没有任何数据可用");
piePlot.setCircular(
false);
piePlot.setLabelGap(
0.02D);

piePlot.setIgnoreNullValues(
true);// 设置不显示空位
piePlot.setIgnoreZeroValues(true);// 设置不显示负值或零值

String tpPath = "D:\\tp\\pie.png"; File file
= new File(tpPath);
if (file.exists()) {
file.delete();
}
try {
ChartUtilities.saveChartAsPNG(file, chart,
800, 500);
File file2
= new File("D:\\tp\\test1.docx");
WordprocessingMLPackage wPackage
= WordprocessingMLPackage.load(new FileInputStream(file2));
MainDocumentPart mainDocumentPart
= wPackage.getMainDocumentPart();
Document wmlDoc
= (Document) mainDocumentPart.getJaxbElement();
Body body
= wmlDoc.getBody();
// 提取正文中所有段落
List<Object> paragraphs = body.getContent();
// 提取书签并创建书签的游标
RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
new TraversalUtil(paragraphs, rt);
for (CTBookmark bm : rt.getStarts()) {
if (bm.getName().equals("test")) {// 这里的test为 word文档中预设的 书签名
BufferedImage image =ImageIO.read(new File(tpPath));
//下面为在图片上插入字符串 <!--

            // Graphics g = image.getGraphics();
             // 设置颜色
            // g.setColor(Color.black);

             // 设置字体
             //java.awt.Font mFont = new java.awt.Font("Arial", java.awt.Font.PLAIN, 11);// 默认字体
            // g.setFont(mFont);

             // 输出文字,不能传入null
            // g.drawString(jzcsyl==null?"0":jzcsyl, 377, 19);
            // g.drawString(zzcjll==null?"0":zzcjll, 181, 99); //-->

byte[] bytes = ChartUtilities.encodeAsPNG(image);
BinaryPartAbstractImage imagePart
= BinaryPartAbstractImage.createImagePart(wPackage, bytes);
Inline inline
= imagePart.createImageInline(null, null, 0, 1, false, 10000);//这里的100000不是正常屏幕大小,用于设置插入图片的大小
P p
= (P) (bm.getParent());

ObjectFactory factory
= new ObjectFactory();
// R对象是匿名的复杂类型,然而我并不知道具体啥意思,估计这个要好好去看看ooxml才知道
R run = factory.createR();
// drawing理解为画布?
Drawing drawing = factory.createDrawing();

drawing.getAnchorOrInline().add(inline);
run.getContent().add(drawing);
p.getContent().add(run);
}
}
wPackage.save(
new FileOutputStream(new File("D:\\tp\\test1.docx")));

}
catch (IOException e) {

}
}

}

 

最后效果图如下:

Java 替换word文档文字,指定位置插入图片

 

很多地方还来不及去了解,粗糙了些