700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 最新实用版——JAVA使用POI替换Word模板中指定字符 并可插入图片。

最新实用版——JAVA使用POI替换Word模板中指定字符 并可插入图片。

时间:2023-11-08 06:04:01

相关推荐

最新实用版——JAVA使用POI替换Word模板中指定字符 并可插入图片。

JAVA替换Word模板指定字符,并可插入图片。

在一年之前还之前有写过一篇使用jacob对word插入图片的博客。点击率蛮高8800多次,当然多亏了百度搜索引擎的帮忙😳

但是小编在使用以前写的代码走了一遍流程时,发现代码貌似会报错:

即使我把这个.dll文件放到指定位置,依然不可取。下面推荐大家一套POI替换指定字符和插入图片的工具类,

如果帮到请你点个赞吧,如果有什么优化建议,也欢迎留言讨论哈😁

我使用的依旧是springboot项目,先导入两个POI依赖

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.14</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.14</version></dependency>

首先创建一个继承XWPFDocument的类,写一个创建图片的方法。之后会使用该类进行创建图片(poi创建图片有bug),因为继承了XWPFDocument,所以后续的使用中不会报错。

/*** @Author: SONGTIANk* @Description: 继承XWPF类,写一个创建图片方法* @Date: /11/11 17:42* @Version: 1.0*/public class CustomXWPFDocument extends XWPFDocument {public CustomXWPFDocument(InputStream in) throws IOException {super(in);}public CustomXWPFDocument() {super();}public CustomXWPFDocument(OPCPackage pkg) throws IOException {super(pkg);}/*** @param id* @param width 宽* @param height 高* @param paragraph 段落*/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=\"/drawingml//main\">"+" <a:graphicData uri=\"/drawingml//picture\">"+"<pic:pic xmlns:pic=\"/drawingml//picture\">"+" <pic:nvPicPr>" + " <pic:cNvPr id=\""+ id+"\" name=\"Generated\"/>"+" <pic:cNvPicPr/>"+" </pic:nvPicPr>"+" <pic:blipFill>"+" <a:blip r:embed=\""+ blipId+"\" xmlns:r=\"/officeDocument//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("测试");}}

之后就是Word工具类了,看一下注释吧

import org.apache.poi.xwpf.usermodel.*;import java.io.*;import java.util.*;import java.util.regex.Matcher;import java.util.regex.Pattern;/*** @Author: SONGTIANk* @Description: Word替换字符和插入图片工具类* @Date: /11/11 17:16* @Version: 1.0*/public class WordUtils {/*** 根据模板生成word* @param path模板的路径* @param params 需要替换的参数* @param fileName 生成word文件的文件名* @tips 此处为了方便而将文件生成在了本地,* 你也可以直接将文件放入response 响应头中,调用浏览器的下载器直接下载到本地,* 这样更符合业务逻辑,即:数据库或者页面输入数据到word模板中,自动生成word并下载;* 也可使用插入图片,替换需要在业务中插入的电子签名,或者盖章的word文档。* 当然了,此处的传参就需要多加一个 HttpServletResponse response* 文件名写中文会有乱码,具体如何调用浏览器下载和解决乱码问题可参考我的另一篇* [简便的Excel导出功能](/weixin_43238452/article/details/108790379)的解决办法。*/public void getWord(String path, Map<String, Object> params,String fileName) throws Exception {File file = new File(path);//创建输入流InputStream is = new FileInputStream(file);//创建doc对象CustomXWPFDocument doc = new CustomXWPFDocument(is);//替换文本里面的变量this.replaceInPara(doc, params); //输出流写入文件FileOutputStream out = new FileOutputStream(fileName);doc.write(out);//关闭输入输出流this.close(is);out.close();System.out.println("<-----生成结束----->");}/*** 替换段落里面的变量* @param doc 要替换的文档* @param params 参数*/private void replaceInPara(CustomXWPFDocument doc, Map<String, Object> params) {Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();XWPFParagraph para;while (iterator.hasNext()) {para = iterator.next();this.replaceInPara(para, params, doc);}}/*** 替换段落里面的变量* @param para 要替换的段落* @param params 参数*/private void replaceInPara(XWPFParagraph para, Map<String, Object> params, CustomXWPFDocument doc) {List<XWPFRun> runs;Matcher matcher;if (this.matcher(para.getParagraphText()).find()) {runs = para.getRuns();int start = -1;int end = -1;String str = "";for (int i = 0; i < runs.size(); i++) {XWPFRun run = runs.get(i);String runText = run.toString();if ('$' == runText.charAt(0) && '{' == runText.charAt(1)) {start = i;}if ((start != -1)) {str += runText;}if ('}' == runText.charAt(runText.length() - 1)) {if (start != -1) {end = i;break;}}}for (int i = start; i <= end; i++) {para.removeRun(i);i--;end--;}for (Map.Entry<String, Object> entry : params.entrySet()) {String key = entry.getKey();if (str.indexOf(key) != -1) {Object value = entry.getValue();if (value instanceof String) {str = str.replace(key, value.toString());para.createRun().setText(str, 0);break;} else if (value instanceof Map) {str = str.replace(key, "");Map pic = (Map) value;int width = Integer.parseInt(pic.get("width").toString());int height = Integer.parseInt(pic.get("height").toString());int picType = getPictureType(pic.get("type").toString());byte[] byteArray = (byte[]) pic.get("content");ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);try {//int ind = doc.addPicture(byteInputStream,picType);//doc.createPicture(ind, width , height,para);doc.addPictureData(byteInputStream, picType);doc.createPicture(doc.getAllPictures().size() - 1, width, height, para);para.createRun().setText(str, 0);break;} catch (Exception e) {e.printStackTrace();}}}}}}/*** 正则匹配字符串* @param str* @return*/private Matcher matcher(String str) {Pattern pattern = pile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(str);return matcher;}/*** 根据图片类型,取得对应的图片类型代码* @param picType* @return int*/private static int getPictureType(String picType) {int res = CustomXWPFDocument.PICTURE_TYPE_PICT;if (picType != null) {if (picType.equalsIgnoreCase("png")) {res = CustomXWPFDocument.PICTURE_TYPE_PNG;} else if (picType.equalsIgnoreCase("dib")) {res = CustomXWPFDocument.PICTURE_TYPE_DIB;} else if (picType.equalsIgnoreCase("emf")) {res = CustomXWPFDocument.PICTURE_TYPE_EMF;} else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {res = CustomXWPFDocument.PICTURE_TYPE_JPEG;} else if (picType.equalsIgnoreCase("wmf")) {res = CustomXWPFDocument.PICTURE_TYPE_WMF;}}return res;}/*** 将输入流中的数据写入字节数组* @param in* @return*/public static byte[] inputStream2ByteArray(InputStream in, boolean isClose) {byte[] byteArray = null;try {int total = in.available();byteArray = new byte[total];in.read(byteArray);} catch (IOException e) {e.printStackTrace();} finally {if (isClose) {try {in.close();} catch (Exception e2) {e2.getStackTrace();}}}return byteArray;}/*** 关闭输入流* @param is*/private void close(InputStream is) {if (is != null) {try {is.close();} catch (IOException e) {e.printStackTrace();}}}}

word和测试类

public static void main(String[] args) {WordUtils wordUtil=new WordUtils();Map<String, Object> params = new HashMap<String, Object>();params.put("${position}", "java开发");params.put("${name}", "焦糖橙子");params.put("${sex}", "男");params.put("${eMail}", "8888@");try{Map<String,Object> jpeg1 = new HashMap<String, Object>();jpeg1.put("width", 100);jpeg1.put("height", 150);jpeg1.put("type", "jpg");jpeg1.put("content", WordUtils.inputStream2ByteArray(new FileInputStream("D:\\text\\cat.jpg"), true));params.put("${jpeg1}",jpeg1);Map<String,Object>jpeg2 = new HashMap<String, Object>();jpeg2.put("width", 100);jpeg2.put("height", 150);jpeg2.put("type", "jpg");jpeg2.put("content", WordUtils.inputStream2ByteArray(new FileInputStream("D:\\text\\dog.jpg"), true));params.put("${jpeg2}",jpeg2);//模板文件位置String path="D:\\text\\myword.docx"; //生成文件位置String fileName= new String("D:\\text\\myTest.docx".getBytes("UTF-8"),"iso-8859-1");wordUtil.getWord(path,params,fileName);}catch(Exception e){e.printStackTrace();}}

执行结果

至此工具类结束

欢迎大家留言讨论

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。