-
2021-04-22 18:54:01
- 1、【Java】使用freemarker模板技术导出word
- main方法测试
package com.havenliu.document; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; public class Main { /** * @param args * @throws UnsupportedEncodingException */ public static void main(String[] args) throws UnsupportedEncodingException { // DocumentHandler dh=new DocumentHandler(); // dh.createDoc(); // MyTest mt=new MyTest(); // mt.createDoc(); Map<String, Object> dataMap = new HashMap<String, Object>(); dataMap.put("name", "你好邱林和"); MDoc mdoc = new MDoc(); mdoc.createDoc(dataMap, "D:/outFile.doc"); System.out.println("模板生成成功"); } }
- Jfinal接口测试
/** * 导出领导人员考核报告word */ @Clear(AppSessionInterceptor.class) public void exportLdrykhbgWord(JSONObject jsonParam) { JSONObject params = kit.get(jsonParam, "params"); Khry khry = params.toJavaObject(Khry.class); Map<String, Object> dataMap = new HashMap<String, Object>(); dataMap.put("name", khry.getName()); dataMap.put("image", MDoc.getImgFileToBase64(khry.getSex())); MDoc mdoc = new MDoc(); try { mdoc.createDoc(dataMap, "d:/ldrykhbg-" + new Date().getTime() + ".doc"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } System.out.println("模板生成成功"); }
- 工具类
package com.longway.core.toolbox.utils; import java.io.*; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import sun.misc.BASE64Encoder; public class MDoc { private Configuration configuration = null; public MDoc() { configuration = new Configuration(); configuration.setDefaultEncoding("utf-8"); } public void createDoc(Map<String, Object> dataMap, String fileName) throws UnsupportedEncodingException { // dataMap 要填入模本的数据文件 // 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载, // 这里我们的模板是放在com.havenliu.document.template包下面 configuration.setClassForTemplateLoading(this.getClass(), "/_template"); Template t = null; try { // test.ftl为要装载的模板 // t = configuration.getTemplate("test_word.ftl"); t = configuration.getTemplate("img.ftl"); } catch (IOException e) { e.printStackTrace(); } // 输出文档路径及名称 File outFile = new File(fileName); Writer out = null; FileOutputStream fos = null; try { fos = new FileOutputStream(outFile); OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8"); // 这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。 // out = new BufferedWriter(new OutputStreamWriter(new // FileOutputStream(outFile))); out = new BufferedWriter(oWriter); } catch (FileNotFoundException e1) { e1.printStackTrace(); } try { t.process(dataMap, out); out.close(); fos.close(); } catch (TemplateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 根据图片路径获取图片并转换位base64格式字符串 * imgFile 图片本地存储路径 */ public static String getImgFileToBase64(String imgFile) { //将图片文件转化为字节数组字符串,并对其进行Base64编码处理 InputStream inputStream = null; byte[] buffer = null; //读取图片字节数组 try { inputStream = new FileInputStream(imgFile); int count = 0; while (count == 0) { count = inputStream.available(); } buffer = new byte[count]; inputStream.read(buffer); } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { // 关闭inputStream流 inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } // 对字节数组Base64编码 return new BASE64Encoder().encode(buffer); } }
- 2、【Java】用Freemarker完美导出word文档(带图片)
- 将图片写入word
在加入了图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image},也就是Map<String, Object>中key,值必须要处理成base64;
代码如:<w:binData w:name=“wordml://自定义.png” xml:space=“preserve”>${image}</w:binData>
注意:“>${image}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。
/** * imgFile 图片本地存储路径 */ public static String getImgFileToBase64(String imgFile) { //将图片文件转化为字节数组字符串,并对其进行Base64编码处理 InputStream inputStream = null; byte[] buffer = null; //读取图片字节数组 try { inputStream = new FileInputStream(imgFile); int count = 0; while (count == 0) { count = inputStream.available(); } buffer = new byte[count]; inputStream.read(buffer); } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { // 关闭inputStream流 inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } // 对字节数组Base64编码 return new BASE64Encoder().encode(buffer); }
- 项目实例
public static void main(String[] args) throws UnsupportedEncodingException { Map<String, Object> dataMap = new HashMap<String, Object>(); dataMap.put("name", "szm"); dataMap.put("image", getImgFileToBase64("d://wxm.jpeg")); MDoc mdoc = new MDoc(); mdoc.createDoc(dataMap, "d:/ldrykhbg-" + new Date().getTime() + ".doc"); System.out.println("模板生成成功"); }
更多相关内容 -
如何批量导出WORD文档中的图片.mp4
2021-02-18 17:48:06有的时候我们Word文档里的图片太多比如超过20张以上 一个一个复制再导出来太麻烦了 但是单个图片导出来有的同学就不会 跟别说导出一大堆图片了 单个图片导出方法 我简单演示一下 看我操作 通过微信发给任何一个... -
Java实现用Freemarker完美导出word文档(带图片)
2020-08-29 23:24:41主要介绍了Java实现用Freemarker完美导出word文档(带图片),具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
java导出图片到word文档
2018-07-30 10:56:43java:多个图片导出到word文档里显示,用于打印图片导出 -
echart图表导出到word文档
2020-07-19 22:47:27poi 将echar报表生成到word中,通过base64格式把图表信息传到后台,后台自动生成word文档,当然可以根据模板自动填充数据,这个小案例只是根据自己需要生成文档,根据自定义模板再拼接自定义内容也有,需要的联系我... -
C#向PPT文档插入图片以及导出图片的实例
2020-08-31 21:50:56PowerPoint演示文稿是我们日常工作中常用的办公软件之一,本篇文章介绍了C#向PPT文档插入图片以及导出图片的实例,非常具有实用价值,需要的朋友可以参考下。 -
js将HTML文本导出生成word文档
2020-11-27 11:36:20js将HTML导出生成word文档,方式简单,不需要修改浏览器配置,引入两个js就可以解决该问题,亲测有效 -
Springboot 项目导出word文档(文档内容包括数据以及服务器图片)
2018-08-30 17:55:25Springboot 项目freemarker导出word文档(文档内容包括数据以及服务器图片) 前些天有需求要完成导出word文档功能,基础数据导出word文档,网上也能搜到很多源代码,但是我这边要求是服务器上的图片(只给出服务器图片...Springboot 项目freemarker导出word文档(文档内容包括数据以及服务器图片)
前些天有需求要完成导出word文档功能,基础数据导出word文档,网上也能搜到很多源代码,但是我这边要求是服务器上的图片(只给出服务器图片路径,从服务器得到图片),前前后后加起来就不好内容了,网上并没有找到处理这种的代码和解决方式,只好自己写了,弄完了来记录下,防止以后再用.
首先动手之前整理下思路:
第一: 分析下word文档内容: 数据 + 图片
- 数据 ——— 数据库获取
- 图片 ——— 拿到数据库连接地址,获取服务器图片.(重点)
第二:分析下实现思路
1. 数据部分很好处理,后面代码上直接可以一步完成
2. 图片部分需要注意一下
2.1.获取数据库图片链接(这个简单跟数据一样处理) 2.2.根据链接从服务器获取图片并保存到本地 2.2.1.注意:数据库得到的图片链接,要想从服务器获取,有的字符是需要转义的,这个需要操作的 2.3.读取本地的图片,将图片信息转为base64,存入跟普通数据一起的实体类中 2.4.将这个实体类导出到指定的word模板中
上述仅仅为简单分析,实际的编写过程中肯定会遇到很多需要额外操作的内容,后面为大家分析.
那么现在就开始编写代码吧:我们用到的技术为freemarker,其实有好多导出文档的技术,这边就不多说了.
第一步:添加pom.xml 我们所需要的依赖,这边我就把我差不多要用的拿出来了,代码太多了就不全粘了.
当然重点就是freemarker.<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.16</version> <scope>provided</scope> </dependency> <!-- JSONObject对象依赖的jar包 --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>net.sf.ezmorph</groupId> <artifactId>ezmorph</artifactId> <version>1.0.6</version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.3</version> <classifier>jdk15</classifier><!-- 指定jdk版本 --> </dependency> <!-- Json依赖架包下载 --> <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5</version> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-support</artifactId> <version>2.1.9</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.23</version> </dependency> </dependencies>
首先我们需要数据,也就是从数据库里面获取到的数据,这个我就不写了,就是简单的从数据库获取数据而已,数据的格式为List< Map< String,Object>> resList 集合.
现在就相当于我们已经有数据了,它就是resList,里面有很多字段信息,包括图片的链接(我这边就先给出两个图片字段 jjyp,yjtp链接吧),http://192.168.0.101:1110/GPRS/Ⅰ临无40 (1).jpg ,http://192.168.0.101:1110/GPRS/Ⅰ临无40 (2).jpg (虚拟链接).
拿到了图片的链接地址,我们就要从服务器获取图片了,并且将它保存到本地 .但是呢再次之前我们还要做的就是图片链接转码,可以直接访问图片链接,地址栏上面的链接就是转码之后的链接(浏览器自动转码),但是代码里面并不会自动转的,所以这里我们要手动转下码才行:
public class CnToEncode { /** * @author 一只会飞的猪 * 将字符串中的中文进行编码 * @param s * @return 返回字符串中汉字编码后的字符串 */ public String charToEncode(String s) throws UnsupportedEncodingException { char[] ch = s.toCharArray(); String result = ""; for(int i=0;i<ch.length;i++){ char temp = ch[i]; if(isChinese(temp)){ try { // 遇到中文给中文转码 String encode = URLEncoder.encode(String.valueOf(temp), "utf-8"); result = result + encode; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } }else{ // 判断是不是空格,是空格时转为 %20 if(temp==' '){ result = result + "%20"; }else{ // 判断字符是否为全角字符 if((int)temp>255){ String encode = URLEncoder.encode(String.valueOf(temp), "utf-8"); result = result + encode; }else { result = result + temp; } } } } return result; } /** * 判断字符是否为汉字 * @param c * @return */ private boolean isChinese(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) { return true; } return false; } }
上面是我写好的方法,可以直接拿来用的.转码之后,你的图片链接就可以在代码里面访问服务器图片了,下面就来写访问服务器图片并返回图片输入流:
public static InputStream getUrlImages(String imagesurl) throws UnsupportedEncodingException { InputStream inputStream = null; HttpURLConnection httpURLConnection = null; try { URL url = new URL(imagesurl); if (url != null) { httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setConnectTimeout(9000); httpURLConnection.setRequestMethod("GET"); int responseCode = httpURLConnection.getResponseCode(); if (responseCode == 200) { inputStream = httpURLConnection.getInputStream(); } } } catch (Exception e) { e.printStackTrace(); } return inputStream; }
然后保存到本地:
// 将服务器图片保存到本地 输入流---->转为输出流写到文件中 public void ImageSaveLocal(String imagepath,String imagename,String imageurl) throws UnsupportedEncodingException { CnToEncode cntoencode = new CnToEncode(); String imagesurl=cntoencode.charToEncode(imageurl); int len = 0; FileOutputStream fileOutputStream = null; InputStream inputStream = getUrlImages(imagesurl); // 得到服务器图片的输入流 // 创建文件夹 File file = new File(imagepath); if (file.exists()) { if (!file.isDirectory()) { file.mkdir(); } } else { file.mkdir(); } try { byte[] imagesize = new byte[inputStream.available()]; // 图片长度缓存数组 fileOutputStream = new FileOutputStream(imagepath + "/" + imagename); // 将要写入的图片地址 while ((len = inputStream.read(imagesize)) != -1) { fileOutputStream.write(imagesize, 0, len); // 写入图片 } } catch (IOException e) { e.printStackTrace(); } finally { try { // 关闭流 fileOutputStream.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
我这边对文件夹的做了一个分类,有需要的可以看下,是按照图片链接的类别分的,比如gps是一类.
既然图片已经保存到了本地了,那么接下来就要读取本地的图片信息了.
// 图片数据转Base64字节码 字符串 // imgFile是上面存到本地的图片路径 public String getImageStr(String imgFile){ InputStream in=null; byte[] data=null; try { in=new FileInputStream(imgFile); data=new byte[in.available()]; in.read(data); in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } BASE64Encoder encoder=new BASE64Encoder(); return encoder.encode(data); }
整理下思路我们做了什么.
上面的各种方法让我们能够将服务器上面的图片存到本地,然后得到图片的base64字节码,图片的base64字节码是可以到处 word的也是能够显示的,咦~那我们是不是就可以到处了呢?nonono 现在还差一步,那就是把普通的数据和你处理之后的 图片 base64数据重新封装到一个Map集合中,这样一来,原数据集合中的图片数据就是我们所需要的base64字节码了啊,这样就能 完整的导出啦.
那现在我们在整个用来封装的方法:
// 参数介绍:jsondata 这个参数是json字符串是你的图片字段名,没有这个系统是不会知道你哪些字段是图片的. // map: 这个当然就是我们的数据了,包括了图片字段数据哦,后面给它替换了就行了 starturl: 这个是服务器图片前缀,这你们根据需要而定 imagespath:图片临时保存地址,也就是我门本地的图片地址了 public Map<String,Object> JsonToMap(String jsondata,Map<String,Object> map,String starturl,String imagepath) throws UnsupportedEncodingException { // starturl="http://101.37.20.41:9004/"; Map<String,Object> resmap = new HashMap<>(); // 解析json字符串 JSONObject jsonObject = JSONObject.fromObject(jsondata); resmap = jsonObject; // 将图片字段名转为map,后面好使用 // 实现源数据的图片数据被base64字节码替换 for ( String key : resmap.keySet()) { if ("".equals(map.get(key)) || map.get(key) == null) { String image = getImageStr(imagepath + "/" + "空白.jpg"); map.put(key,image); } else { String imageurl = starturl + map.get(key); String imagename = (String) map.get(key); String filetype = imagename.substring(0, imagename.indexOf("/")); // 截取字段值"/" 之前的字符串作为二级文件夹 // 创建本地的二级文件夹 File file = new File(imagepath + "/" + filetype); if (file.exists()) { if (!file.isDirectory()) { file.mkdir(); } } else { file.mkdir(); } // 拉取服务器图片存入本地 ImageSaveLocal(imagepath, imagename, imageurl); // 图片转码 String image = getImageStr(imagepath + "/" + imagename); map.put(key, image); } } return map; }
这样以来我们就得到了完美的数据结果了map.
各位观众!接下来就开始导出word文档了.开始之前我们要制作一个xml文档模板,这个至于怎么做网上有好多教程,当然坑也多.
那我们就上代码了:package com.jshhxx.commontoolsservice.controller; import com.jshhxx.commontoolsservice.common.AbstractController; import com.jshhxx.commontoolsservice.common.FileToZip; import com.jshhxx.commontoolsservice.common.ImagesFileCommon; import com.jshhxx.commontoolsservice.common.MapKeyToLowercase; import com.jshhxx.commontoolsservice.service.ExportWord.ExportWordService; import org.apache.ibatis.annotations.Param; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import java.io.*; import java.util.*; import static com.jshhxx.commontoolsservice.common.FileToZip.fileToZip; @RestController public class ExportController extends AbstractController { /** * @Autor 一只会飞猪 * @dis 信息导出word文档 * @param wordType 给文档分类 gps/fcb 等 * @param reslut 数据 * @param wordPath 导出路径 * @param wordname 导出名称(单条数据导出命名有效,多条数据导出zip无效) * @param wordfieldname 批量导出名称字段 * @param templatename 模板名称 * @Param jsondata 图片字段json * * */ @Autowired private ExportWordService exportWordService; private static Logger log = LoggerFactory.getLogger(ExportController.class); @Value("${ToWordPath}") private String ToWordPath; @Value("${ImagePath}") private String ImagePath; @PostMapping("/genWord") public Map<String,String> genWord(Model model, @RequestBody List<Map<String,Object>> resListone, @Param("wordType") String wordType, @Param("wordname") String wordname, @Param("wordfieldname") String wordfieldname, @Param("templatename") String templatename, @Param("jsondata") String jsondata, @Param("starturl") String starturl ) throws UnsupportedEncodingException { boolean ret = false; String msg = null; boolean flag=false; FileToZip fileToZip = new FileToZip(); Map<String,String> result=new HashMap<>(); Map<String,Object> resMap = new HashMap<>(); List<Map<String,Object>> resList = new ArrayList<>(); MapKeyToLowercase mapKeyToLowercase = new MapKeyToLowercase(); ImagesFileCommon imagesFileCommon = new ImagesFileCommon(); String outputFilePath = ToWordPath; // 获取程序的当前路径 C:/wordgenerator // 创建导出word文档路径 filepath1:文件基础目录路径 C:\wordgenerator, // filepath2:文件分类路径 C:\wordgenerator\gps // filepath3:文件最终导出路径 C:\wordgenerator\gps\gps15341394803391208 String num = String.valueOf((int)(Math.random()*9000+1000)); String filepath1=outputFilePath; String filepath2=filepath1+"/"+wordType; String zzfile="/"+wordType+System.currentTimeMillis(); String filepath3=filepath2+zzfile+num; // 创建文件夹 String wordPath=createfile(filepath1,filepath2,filepath3); String resultPath = "/"+wordType+zzfile; //将map中的key全转为小写,以便模板注入.JsonToMap() 图片数据处理 for(int j=0;j<resListone.size();j++){ resMap=mapKeyToLowercase.transformUpperCase(imagesFileCommon.JsonToMap(jsondata,resListone.get(j),starturl,ImagePath)); resList.add(resMap); } // 指定目录下的新建文件夹,针对每次操作都给以唯一的文件夹存放文件 try { // 导出word文档 if (!resList.isEmpty()) { if(resList.size()==1){ Writer out = null; if("".equals(wordname)||wordname==null){ wordname = "新建word文档"; out = new OutputStreamWriter(new FileOutputStream(wordPath+"/"+wordname+".doc"), "UTF-8"); exportWordService.createWord("/",templatename+".xml", resList.get(0), out); result.put("url",resultPath +"/"+ wordname + ".doc"); }else{ out = new OutputStreamWriter(new FileOutputStream(wordPath+"/"+wordname+".doc"), "UTF-8"); exportWordService.createWord("/",templatename+".xml", resList.get(0), out); result.put("url",resultPath +"/"+ wordname + ".doc"); } out.close(); }else { for (int i = 0; i < resList.size(); i++) { Writer out = null; // 如果有绑定的数据字段则以数据库数据为文件名 wordname= (String) resList.get(i).get(wordfieldname); if("".equals(wordname)||wordname==null){ wordname = "新建word文档"+(i+1); } try { out = new OutputStreamWriter(new FileOutputStream(wordPath + "/"+wordname + ".doc"), "UTF-8"); exportWordService.createWord("/", templatename + ".xml", resList.get(i), out); out.close(); } catch (UnsupportedEncodingException | FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 打成压缩包 // 判断是是否有指定的分类别 if(wordType==null||"".equals(wordType)){ wordname= String.valueOf(System.currentTimeMillis())+num; flag = fileToZip(ToWordPath, ToWordPath,wordname); result.put("url", "/"+wordname+".zip"); }else { wordname= wordType+"_"+String.valueOf(System.currentTimeMillis())+num; flag = fileToZip(wordPath, wordPath,wordname); result.put("url",resultPath +"/"+ wordname + ".zip"); } if(flag){ log.error("===========================文件打包成功==========================="); }else{ log.error("===========================文件打包失败==========================="); } } } } catch (Exception e) { msg = e.getMessage(); } if((!"".equals(result))||result!=null){ ret = true; } return result; } // 创建文件夹存放导出的word文件 // filepath1:文件基础目录路径 C:\wordgenerator, // filepath2:文件分类路径 C:\wordgenerator\gps // filepath3:文件最终导出路径 C:\wordgenerator\gps\gps15341394803391208 public static String createfile(String filepath1,String filepath2,String filepath3){ File file1 = new File(filepath1); File file2 = new File(filepath2); File file3 = new File(filepath3); System.out.println(filepath3); try { if (file1.exists()) { if (!file1.isDirectory()) { file1.mkdir(); file2.mkdirs(); file3.mkdirs(); } else { if (!file2.exists()) { if (!file2.isDirectory()) { file2.mkdirs(); file3.mkdirs(); } else { if (!file3.exists()) { file3.mkdirs(); } else { if (!file3.isDirectory()) { file3.mkdirs(); } } } } else { file2.mkdirs(); file3.mkdirs(); } } } else { file1.mkdir(); file2.mkdir(); file3.mkdir(); } }catch (Exception e){ log.error("=======================创建文件夹失败!======================"); } return filepath3; } }
package com.jshhxx.commontoolsservice.service.ExportWord.Impl; import com.jshhxx.commontoolsservice.service.ExportWord.ExportWordService; import com.jshhxx.commontoolsservice.word.MapperTest; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.*; /** * @author 一只会飞的猪 * @dis 查询数据导出word文档 * */ @Service public class ExportWordServiceImpl implements ExportWordService { @Autowired private MapperTest mapperTestm; private Configuration configuration =new Configuration(); // 将数据导入到模板word中,并生成word文档 public void createWord(String templatePath, String templateName, Object dataMap, Writer out) { try { Template t = getTemplate(templatePath, templateName); t.process(dataMap, out); out.close(); } catch (IOException e) { System.out.println(e); } catch (TemplateException e) { System.out.println(e); } finally { try { out.close(); } catch (IOException e) { System.out.println(e); } } } // 模板加载 private Template getTemplate(String templatePath, String templateName) throws IOException { configuration.setClassForTemplateLoading(this.getClass(), templatePath); Template t = configuration.getTemplate(templateName); t.setEncoding("UTF-8"); return t; } }
这样一来就大功告成了,后面的代码讲解的比较少,因为网上很多,主要讲的就是这整个功能的开发思路.
功能是做出来了,但是乱码怎么解决呢?
告诉你们一个小技巧,部署的时候制定下编码就行了,java -jar Dfile.encoding=utf-8 ** -
vue 导出word文档(包括图片)
2022-04-24 13:39:28vue 导出word文档(包括图片)vue 导出word文档(包括图片)
1.安装依赖
-- 安装 docxtemplater npm install docxtemplater pizzip --save -- 安装 jszip-utils npm install jszip-utils --save -- 安装 jszip npm install jszip --save -- 安装 FileSaver npm install file-saver --save
2.创建exportFile.js(导出word方法)
import PizZip from 'pizzip' import docxtemplater from 'docxtemplater' import JSZipUtils from 'jszip-utils' import { saveAs } from 'file-saver' /** * 将base64格式的数据转为ArrayBuffer * @param {Object} dataURL base64格式的数据 */ function base64DataURLToArrayBuffer (dataURL) { const base64Regex = /^data:image\/(png|jpg|jpeg|svg|svg\+xml);base64,/; if (!base64Regex.test(dataURL)) { return false; } const stringBase64 = dataURL.replace(base64Regex, ""); let binaryString; if (typeof window !== "undefined") { binaryString = window.atob(stringBase64); } else { binaryString = new Buffer(stringBase64, "base64").toString("binary"); } const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { const ascii = binaryString.charCodeAt(i); bytes[i] = ascii; } return bytes.buffer; } /** * 导出word,支持图片 * @param {Object} tempDocxPath 模板文件路径 * @param {Object} wordData 导出数据 * @param {Object} fileName 导出文件名 * @param {Object} imgSize 自定义图片尺寸 */ export const exportWord = (tempDocxPath, wordData, fileName, imgSize) => { // 这里要引入处理图片的插件 var ImageModule = require('docxtemplater-image-module-free'); const expressions = require("angular-expressions"); // 读取并获得模板文件的二进制内容 JSZipUtils.getBinaryContent(tempDocxPath, function (error, content) { if (error) { throw error; } expressions.filters.size = function (input, width, height) { return { data: input, size: [width, height], }; }; // function angularParser (tag) { // const expr = expressions.compile(tag.replace(/’/g, "'")); // return { // get (scope) { // return expr(scope); // }, // }; // } // 图片处理 let opts = {} opts = { // 图像是否居中 centered: false }; opts.getImage = (chartId) => { // console.log(chartId);//base64数据 // 将base64的数据转为ArrayBuffer return base64DataURLToArrayBuffer(chartId); } opts.getSize = function (img, tagValue, tagName) { // console.log(img);//ArrayBuffer数据 // console.log(tagValue);//base64数据 // console.log(tagName);//wordData对象的图像属性名 // 自定义指定图像大小 if (imgSize.hasOwnProperty(tagName)){ return imgSize[tagName]; } else { return [600, 350]; } } // 创建一个PizZip实例,内容为模板的内容 let zip = new PizZip(content); // 创建并加载docxtemplater实例对象 let doc = new docxtemplater(); doc.attachModule(new ImageModule(opts)); doc.loadZip(zip); doc.setData(wordData); try { // 用模板变量的值替换所有模板变量 doc.render(); } catch (error) { // 抛出异常 let e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties }; console.log(JSON.stringify({ error: e })); throw error; } // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示) let out = doc.getZip().generate({ type: "blob", mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); // 将目标文件对象保存为目标类型的文件,并命名 saveAs(out, fileName); }); }
3.组件调用
<template> <a-form-model ref="ruleForm" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol" > <a-form-model-item label="名称" prop="name"> <a-input-number v-model="form.name" style="width:100%;"/> </a-form-model-item> <a-form-model-item label="日期" prop="date"> <a-input v-model="form.date" /> </a-form-model-item> <a-form-model-item label="文件"> <a-input v-model="form.imgUrl" read-only/> <a-upload name="file" :showUploadList="false" :customRequest="customRequest"> <a-button type="primary" icon="upload">导入图片</a-button> </a-upload> </a-form-model-item> <a-form-model-item label="操作"> <a-button type="primary" icon="export" @click="exportWordFile">导出word文档</a-button> </a-form-model-item> </a-form-model> </template> <script> import {exportWord} from '@/assets/js/exportFile.js' export default { name: 'ExportFile', data () { return { labelCol: { span: 6 }, wrapperCol: { span: 16 }, form: {}, rules: { name: [ { required: true, message: '请输入名称!', trigger: 'blur' }, ], date:[ { required: true, message: '请输入日期!', trigger: 'blur' }, ], }, }; }, created (){}, methods: { customRequest (data){ //图片必须转成base64格式 var reader = new FileReader(); reader.readAsDataURL(data.file); reader.onload = () => { // console.log("file 转 base64结果:" + reader.result); this.form.imgUrl = reader.result; //imgUrl必须与模板文件里的参数名一致 }; reader.onerror = function (error) { console.log("Error: ", error); }; }, exportWordFile (){ let imgSize = { imgUrl:[65, 65], //控制导出的word图片大小 }; exportWord("./static/test.docx", this.form, "demo.docx", imgSize); //参数1:模板文档 //参数2:字段参数 //参数3:输出文档 //参数4:图片大小 } }, }; </script>
4.创建test.docx文档模板。注:使用vue-cli2的时候,放在static目录下;使用vue-cli3的时候,放在public目录下。
模板参数名需与字段一致,普通字段:{字段名},图片字段:{%字段名}
文档内容:
5.导出demo.docx结果
-
Nodejs导出Excel带图片,Nodejs后台导出带图片Excel
2020-11-03 09:49:19Nodejs导出Excel带图片,Nodejs后台导出带图片Excel 本资源内有说明及使用安装等详细步骤,以及引入插件 由于nodejs导出Excel带图片的资源比较少,我也是找了许久才知道怎么写的,这里发布个收费的,望各位见谅! -
java导出图片,每页4张图
2019-02-14 16:08:08java导出图片到word,要求每页4张图片,客户的特殊需求。如有需要请下载参考。亲测有效,有需要的可以下载试试 -
vue页面导出Word文档(含图片)
2020-08-26 19:48:53}, /** * description: 导出文档 * * created by aa on 2020-08-18 * */ exportWord(){ var ImageModule = require('open-docxtemplater-image-module'); // 点击导出word let _this = this; // 读取并获得模板...引用插件
安装
npm i docxtemplater@3.17.6 npm i pizzip npm i jszip-utils@0.1.0 npm i jszip@2.6.1 npm i file-saver@2.0.2 npm i open-docxtemplater-image-module
引入插件
import docxtemplater from 'docxtemplater' import PizZip from 'pizzip' import JSZipUtils from 'jszip-utils' import {saveAs} from 'file-saver'
Word模板
不要慌,很容易的,新建个word,编写变量即可(demo_word.docx,可将word文档放在static下面)
注:语法可参考网站:https://docxtemplater.com/demo/#loop-table
data数据
echartUrl1: '', clients: [ { "first_name": "John", "last_name": "Doe", "phone": "+44546546454" }, { "first_name": "Jane", "last_name": "Doe", "phone": "+445476454" } ]
页面函数
/** * description: 导出echarts图片,格式转换 * * created by aa on 2020-08-18 * */ base64DataURLToArrayBuffer(dataURL) { const base64Regex = /^data:image\/(png|jpg|svg|svg\+xml);base64,/; if (!base64Regex.test(dataURL)) { return false; } const stringBase64 = dataURL.replace(base64Regex, ""); let binaryString; if (typeof window !== "undefined") { binaryString = window.atob(stringBase64); } else { binaryString = new Buffer(stringBase64, "base64").toString("binary"); } const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { const ascii = binaryString.charCodeAt(i); bytes[i] = ascii; } return bytes.buffer; }, /** * description: 导出文档 * * created by aa on 2020-08-18 * */ exportWord(){ var ImageModule = require('open-docxtemplater-image-module'); // 点击导出word let _this = this; // 读取并获得模板文件的二进制内容 JSZipUtils.getBinaryContent("../../../../static/demo_word.docx",function(error, content) { // exportTemplate.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据 // 抛出异常 if (error) { throw error; } // 图片处理 let opts = {} opts.centered = true; // 图片居中,在word模板中定义方式为{%%image} opts.fileType = "docx"; opts.getImage = function(chartId){ return _this.base64DataURLToArrayBuffer(chartId); } opts.getSize = function(){ return [600,300] } let imageModule = new ImageModule(opts); // 创建一个PizZip实例,内容为模板的内容 let zip = new PizZip(content); // 创建并加载docxtemplater实例对象 let doc = new docxtemplater(); doc.attachModule(imageModule); doc.loadZip(zip); // 设置模板变量的值 doc.setData({ clients: _this.clients, image1:_this.echartUrl1, // 获取echarts图片 }); try { // 用模板变量的值替换所有模板变量 doc.render(); } catch (error) { // 抛出异常 let e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties }; throw error; } // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示) let out = doc.getZip().generate({ type: "blob", mimeType:"application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); // 将目标文件对象保存为目标类型的文件,并命名 saveAs(out, "word文档名称.docx"); }); },
echart图片获取
// 基于准备好的dom,初始化echarts实例 let myChart1 = this.$echarts.init(document.getElementById('myChart1')) // 绘制图表 myChart1.setOption(this.option1); // 获取echart图片 this.echartUrl1 = myChart1.getDataURL();
相关文章:vue导出word文档
-
Springboot实现导出Word文档(包含图片)
2021-10-14 15:34:44Springboot实现导出Word文档(包含图片) 准备工作 首先准备一个Word文档模板(template.docx): 准备一张图片: 查看实际效果: 开发工作 需要的相关依赖: <!-- Poi文件导出依赖(World版本)--> <... -
工具:语雀导出MarkDown文档后图片修复
2021-09-08 09:28:17微信公众号:乌鸦安全 扫取二维码获取更多信息!...语雀确实比较好用,但是缺点也很明显,如果没有网络加载的情况下,是无法查看文档的。就算是在本地的语雀应用,也是无法查看的。 语雀的... -
springboot中使用freemarker动态生成word文档,以及使用POI导出自定义格式Excel
2019-10-22 17:39:34Springboot项目中: 1. 使用Apache POI 3.9 自定义样式导出Excel文件...2. 使用freemarker动态生成word .doc文档(带图片Word以及复杂格式word) 详细说明见个人博客及 github: https://github.com/DuebassLei/excel-poi -
导出API文档为Word/PDF格式
2021-08-23 11:00:10目标:导出所有微服务的API文档,并汇总到一个文档中去。 2 解决 解决思路:Swagger2文档导入到YAPI -> YAPI导出为Markdown格式 -> 在线Markdown格式转换为Word文档 2.1 Swagger2文档导入到YAPI 项目中... -
c#导出word文件(附带图片)
2018-05-23 16:16:19c#导出word文件,附带word纸张页边距,字体,行边距,间距紧缩比 磅值等的设置。使用的时候需要引用dll -
java数据源导出WORD文档(包括图片、表格及文本)
2009-11-19 11:47:21最近因项目开发的需要,整理了一份用JAVA导出WORD文档,其部署步骤如下: 1、将jacob-1.14.3-x86.dll放在服务器的系统盘(或运行本机的系统):\WINDOWS\system32目录下。 2、将jacob-1.14.3-x86.dll放在JDK 的 bin ... -
Java 用Freemarker完美导出word文档(带图片)
2022-04-12 14:35:52第三步:找到图片base64,删除base64替换成占位符${image},只修改图片的,其余的不用动 第四步:加入依赖 <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker&... -
Java导出Word文档的实现
2020-10-18 16:17:13在日常的开发工作中,我们时常会遇到导出Word文档报表的需求,比如公司的财务报表、医院的患者统计报表、电商平台的销售报表等等。 导出Word方式多种多样,通常有以下几种方式: 1. 使用第三方Java工具类库Hutool... -
Java 导出word文档,遍历表格数据,导出图片
2022-01-19 17:51:16//导出单个数据 dataMap.put("title","我是导出文档的标题");//导出对象 Map, String> user = new HashMap(); user.put("name", "姓名"); user.put("age", "443"); user.put("address", "地址"); user.put("other",... -
TinyMCE富文本编辑器导出为word文档(JS实现)
2020-11-16 16:43:25应用JS实现,TinyMCE富文本编辑器导出为word文档,可解决图片,表格的导出,这是实现的demo,可以直接取用 -
导出world文档
2014-10-11 13:39:44在java中,可以利用poi-3.8-20120326.jar、popoi-excelant-3.8-20120326.jar、poi-ooxml-3.8-20120326.jar、poi-ooxml-schemas-3.8-20120326.jar、poi-scratchpad-3.8-20120326.jar、stax-api-1.0.1....导出world文档. -
Mac如何快速导出保存Pages文档里的图片
2021-04-14 10:08:03如何快速导出保存Pages文档里的图片? 首先把 pages 文档修改成 .rar 格式 1、选中 .pages 文件回车,修改 .pages 为 .rar。 2、解压修改的 .rar。 3、在解压的 .rar 文件夹找到一个Data的文件夹。你会发现 ... -
用python爬取网页并导出为word文档.docx
2020-05-06 14:58:45由于mongodb是文档型数据库,区别于传统的数据库,它是用来管理文档的。在传统的数据库中,信息被分割成离散的数据段,而在文档数据库中,文档是处理信息的基本单位。一个文档可以很长、很复杂、可以无结构,与字... -
java导出图片到word简易写法
2017-10-20 16:56:26java语言,后台导出图片到word文档中,这是一种简易的写法,基本上一眼即可看懂。亲测有效。如果有需要的,可以下载进行参考。 -
在线导出word文件
2018-04-13 12:41:08实现在线导出word文件。实现在线导出word文件。实现在线导出word文件。实现在线导出word文件。实现在线导出word文件。 -
java后台导出word文档正文、表格、图片
2022-01-07 10:13:19java后台导出word文档正文、表格、图片 -
Java将数据和图片导入word文档以及html5绘图(highcharts,exporting.js;服务端导出)
2018-01-12 14:10:51上传内容包括 1,将java后台获取的数据写入...2,将图片导入word文档并导出(注意:导出图片在word模板上需要先随便找张图片先放入指定位置,另存为xml之后打开,将先前放入的图片xml删掉,做个标识符(例如:${abc}))