java/poi讀取word,並替換word中的文字內容,向word中插入圖片的操作
阿新 • • 發佈:2019-01-10
先貼程式碼,注:部分程式碼源自網路其他前輩的文章,這裡只是做一個功能整合。
此類為操作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"); } }
注:此操作只支援word2007及以上版本。在指定位置插入圖片時,必須將需要替換的文字放在單元格中。檔案操作完後,會對原始檔也進行操作,也就是會將原始檔的需要替換的內容也替換掉,就不能達到重複利用原始檔的效果,因此我在下面貼出了複製檔案的方法,將原始檔複製一份,再對複製檔案進行操作,這樣就可以使原始檔多次複用。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(); } } }
感謝其他前輩的程式碼,因為功能做了很久了,所以不記得部分原始碼的出處了。如果有朋友知道,就貼在回覆中。也可以在下面留言,大家一起探討。