1. 程式人生 > >Java Poi 根據文字內容 插入 word 圖片

Java Poi 根據文字內容 插入 word 圖片

需求描述

如下圖,我需要在word里根據一個圖片的名字,將名字替換成該圖片(公章)
在這裡插入圖片描述

思路:

用POI遍歷每一個表格裡的每一行的每一個單元格,如果遇到我自己定義的"&章",則獲取後面的圖片的名字,然後利用POI的XWPFRun.addPicture(url,畫素…)方法將圖片新增到word裡,然後將原有的文字清除掉。
注意:圖片要放在表格的單元格里,最後單元格里的文字會被清除掉,只留下圖片

簡單生成圖片和文字的程式碼:

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<String> 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<stamps.size() && i<para.getRuns().size(); 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();
				}
			}
		}
    }
}

最後樣子:涉及保密就加了馬賽克~
在這裡插入圖片描述