java/poi读取word,并替换word中的文本内容,向word中插入图片的操作

先贴代码,注:部分代码源自网络其他前辈的文章,这里只是做一个功能整合。

package fcjTool;  
  
import java.io.IOException;  
import java.io.InputStream;  
  

import org.apache.poi.openxml4j.opc.OPCPackage;  
import org.apache.poi.xwpf.usermodel.XWPFDocument;  
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlException;  
import org.apache.xmlbeans.XmlToken;  
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;  
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;  
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;  
  
public class CustomXWPFDocument extends XWPFDocument {
    public CustomXWPFDocument(InputStream in) throws IOException {
        super(in);
    }
    
    public CustomXWPFDocument() {
        super();
    }
    
    public CustomXWPFDocument(OPCPackage pkg) throws IOException {
        super(pkg);
    }
    
    public void createPicture(int id, int width, int height,XWPFParagraph paragraph) {
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;
        String blipId = getAllPictures().get(id).getPackageRelationship()
                .getId();    
    
        CTInline inline = paragraph.createRun().getCTR()    
                .addNewDrawing().addNewInline();    
    
        String picXml = ""    
                + "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"    
                + "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"    
                + "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"    
                + "         <pic:nvPicPr>" + "            <pic:cNvPr id=\""    
                + id    
                + "\" name=\"Generated\"/>"    
                + "            <pic:cNvPicPr/>"    
                + "         </pic:nvPicPr>"    
                + "         <pic:blipFill>"    
                + "            <a:blip r:embed=\""    
                + blipId    
                + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"    
                + "            <a:stretch>"    
                + "               <a:fillRect/>"    
                + "            </a:stretch>"    
                + "         </pic:blipFill>"    
                + "         <pic:spPr>"    
                + "            <a:xfrm>"    
                + "               <a:off x=\"0\" y=\"0\"/>"    
                + "               <a:ext cx=\""    
                + width    
                + "\" cy=\""    
                + height    
                + "\"/>"    
                + "            </a:xfrm>"    
                + "            <a:prstGeom prst=\"rect\">"    
                + "               <a:avLst/>"    
                + "            </a:prstGeom>"    
                + "         </pic:spPr>"    
                + "      </pic:pic>"    
                + "   </a:graphicData>" + "</a:graphic>";    
    
        inline.addNewGraphic().addNewGraphicData();
        XmlToken xmlToken = null;
        try {    
            xmlToken = XmlToken.Factory.parse(picXml);
        } catch (XmlException xe) {    
            xe.printStackTrace();    
        }    
        inline.set(xmlToken);    
    
        inline.setDistT(0);    
        inline.setDistB(0);    
        inline.setDistL(0);    
        inline.setDistR(0);    
    
        CTPositiveSize2D extent = inline.addNewExtent();    
        extent.setCx(width);    
        extent.setCy(height);    
    
        CTNonVisualDrawingProps docPr = inline.addNewDocPr();    
        docPr.setId(id);    
        docPr.setName("图片" + id);    
        docPr.setDescr("descr");    
    }    
}


此类为操作word文本内容的具体实现类


package fcjTool;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
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;

/**
 * 使用POI,读取word 2007,并实现修改文本内容,在指定位置插入图片,替换表格中的文本内容,并写回到word中
 * @author 付程俊
 *
 */
public class POIReadAndWriteWord2007 {
	public static void main(String[] args) {
		/**源文件的路径,注:只支持word2007,或许还支持word 2010,其他待测试*/
		String filePath = "E:\\test\\POIRedAndWrite.docx";
		String tips = POIReadAndWriteWord2007.readwriteWord(filePath);
		System.out.println(tips);
	}
	/**读取并操作word2007中的内容*/
	public static String readwriteWord(String filePath){
		File isExist = new File(filePath);
		/**判断源文件是否存在*/
		if(!isExist.exists()){
			return "源文件不存在!";
		}
		CustomXWPFDocument document;
		try {
			/**打开word2007的文件*/
			OPCPackage opc = POIXMLDocument.openPackage(filePath);
			document = new CustomXWPFDocument(opc);
			/**替换word2007的纯文本内容*/
			List<XWPFRun> listRun;
			List<XWPFParagraph> listParagraphs = document.getParagraphs();
			for (int i = 0; i < listParagraphs.size(); i++) {
				listRun = listParagraphs.get(i).getRuns();
				for (int j = 0; j < listRun.size(); j++) {
					if("#{text}#".equals(listRun.get(j).getText(0))){
						listRun.get(j).setText("替换的纯文本内容!",0);
					}
				}
			}
			/**取得文本的所有表格*/
			Iterator<XWPFTable> it = document.getTablesIterator();
			while(it.hasNext()){/**循环操作表格*/
				XWPFTable table = it.next();
				List<XWPFTableRow> rows = table.getRows();
				for(XWPFTableRow row:rows){/**取得表格的行*/
					List<XWPFTableCell> cells = row.getTableCells();
					for(XWPFTableCell cell:cells){/**取得单元格*/
						if("#{img}#".equals(cell.getText())){/**判断单元格的内容是否为需要替换的图片内容*/
							File pic = new File("E:\\test\\xiaosimm.png");
							FileInputStream is = new FileInputStream(pic);
							cell.removeParagraph(0);
							XWPFParagraph pargraph = cell.addParagraph();
							document.addPictureData(is, XWPFDocument.PICTURE_TYPE_PNG);
							document.createPicture(document.getAllPictures().size()-1, 600, 395, pargraph);
							if(is != null){
								is.close();
							}
						}
						List<XWPFParagraph> pars = cell.getParagraphs();
						for(XWPFParagraph par:pars){
							List<XWPFRun> runs = par.getRuns();
							for(XWPFRun run:runs){
								run.removeBreak();
							}
						}
						if("#{table}#".equals(cell.getText())){/**判断单元格中是否为需要替换的文本内容*/
							cell.removeParagraph(0);
							cell.setText("替换表格中的文本内容!");
						}
					}
				}
			}
			String downloadPath = "D:\\replace.docx";
			OutputStream os = new FileOutputStream(downloadPath);
			document.write(os);
			if(os != null){
				os.close();
			}
			if(opc != null){
				opc.close();
			}
			return "文件转换成功!路径为:"+downloadPath;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return filePath;
	}

	/**复制文件的方法*/
	public static void copyFile(String oldPath, String newPath) {
		try {
			int bytesum = 0;
			int byteread = 0;
			File oldfile = new File(oldPath);
			if (oldfile.exists()) { //文件存在时
				InputStream inStream = new FileInputStream(oldPath); //读入原文件
				FileOutputStream fs = new FileOutputStream(newPath);
				byte[] buffer = new byte[1444];
				while ( (byteread = inStream.read(buffer)) != -1) {
					bytesum += byteread; //字节数 文件大小
					System.out.println(bytesum);
					fs.write(buffer, 0, byteread);
				}
				inStream.close();
				fs.close();
			}
		}
		catch (Exception e) {
			System.out.println("复制单个文件操作出错");
			e.printStackTrace();
		}
	}
}


注:此操作只支持word2007及以上版本。在指定位置插入图片时,必须将需要替换的文本放在单元格中。文件操作完后,会对源文件也进行操作,也就是会将源文件的需要替换的内容也替换掉,就不能达到重复利用源文件的效果,因此我在下面贴出了复制文件的方法,将源文件复制一份,再对复制文件进行操作,这样就可以使源文件多次复用。

感谢其他前辈的代码,因为功能做了很久了,所以不记得部分源码的出处了。如果有朋友知道,就贴在回复中。也可以在下面留言,大家一起探讨。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值