1. 程式人生 > 實用技巧 >JAVA實現替換WORD模板中的文字和圖片

JAVA實現替換WORD模板中的文字和圖片

1.本來有其他方法可以實現的,但是由於jar包一直有問題所以換了種,要是還有其他的更好的方法,希望可以討論

2.廢話不說直接上程式碼;

3.我自己加了個生成圖片的方法,也可以不需要直接用已經存在的圖片替換即可 ,注意jar包的引入,import的時候看清楚是什麼包!!!先給出MAVEN中pom.xml需要匯入的包

    <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>


package com.example.demo;

import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.poi.POIXMLDocument;
import org.docx4j.wml.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.assertj.core.util.Maps;
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.*;
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.data.general.DefaultPieDataset;

public class ReplaceWordUtils {
//模板路徑
public static final String DOC_PATH = "D:\\report\\test.docx";
//圖片路徑
public static final String IMAGE_PATH = "D:\\report\\test.png";
//替換文字圖片後的路徑
public static final String DOC_PATH2 = "D:\\report\\test1.docx";

//word文件中替換文字方法
public static void replaceContent(Map<String, String> map,String wordPath){
XWPFDocument document = null;
try
{
document = new XWPFDocument(POIXMLDocument.openPackage(wordPath));
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());
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(DOC_PATH2);
document.write(outStream);
outStream.close();
}
catch (Exception e)
{
e.printStackTrace();
}

}

public static void replaceImage(){
//-----------------------------------插入圖片---------------------------------------
File file = new File(IMAGE_PATH);
try {
File file2 = new File(DOC_PATH2);
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("images")) {// 這裡的test為 word文件中預設的 書籤名
InputStream inputStream = new FileInputStream(file);
byte[] bytes = IOUtils.toByteArray(inputStream);
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(DOC_PATH2)));
} catch (Exception e) {
e.printStackTrace();
}
}


//生成圖片
public static void initImg(){
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);// 設定不顯示負值或零值

try
{
ChartUtilities.saveChartAsPNG(new File(IMAGE_PATH), chart, 800, 500);
}
catch (IOException e)
{
e.printStackTrace();
}
}

public static void main(String[] args) throws Exception {
Map<String, String> map = new HashMap<>();
map.put("unit","4");
map.put("startValue","85");
map.put("controlRod10","90");
map.put("plan","35計劃");
map.put("position","總經理處");
//替換文字
replaceContent(map,DOC_PATH);
//生成圖片
initImg();
//替換圖片
replaceImage();
}

}

4.以上是所有程式碼,其中模板截圖如下:箭頭是要替換的文字以及圖片需要插入標籤,替換的時候需要用到

5.最後的結果是這樣的

以上就是整個邏輯程式碼了,可以自己在嘗試下,有的邏輯可以自己改改,有什麼問題可以留言。