Java用freemarker导出Word 文档
1.用Microsoft Office Word打开word原件;
2.把需要动态修改的内容替换成***,如果有图片,尽量选择较小的图片几十K左右,并调整好位置;
3.另存为,选择保存类型Word 2003 XML 文档(*.xml)【这里说一下为什么用Microsoft Office Word打开且要保存为Word 2003XML,本人亲测,用WPS找不到Word 2003XML选项,如果保存为Word XML,会有兼容问题,避免出现导出的word文档不能用Word 2003打开的问题】;
4.用Firstobject free XML editor打开文件,选择Tools下的Indent【或者按快捷键F8】格式化文件内容。左边是文档结构,右边是文档内容;
5. 将文档内容中需要动态修改内容的地方,换成freemarker的标识。其实就是Map<String, Object>中key,如${landName};
6.在加入了图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image},也就是Map<String, Object>中key,值必须要处理成base64;
代码如:<w:binData w:name="wordml://自定义.png" xml:space="preserve">${image}</w:binData>
注意:“>${image}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。
如果需要循环,则使用:<#list maps as map></#list> maps是Map<String, Object>中key,值为数组,map为自定义;
7. 标识替换完之后,模板就弄完了,另存为.ftl后缀文件即可。注意:一定不要用word打开ftl模板文件,否则xml内容会发生变化,导致前面的工作白做了。
导出到本地:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.HttpURLConnection; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import com.aspose.words.Document; import com.aspose.words.License; import com.aspose.words.SaveFormat; import freemarker.template.Configuration; import freemarker.template.Template; import sun.misc.BASE64Encoder; public class WordTest { // 此目录路径 要求 完整的路径,并且 windows 不能以 /开头 如 : /c:/xxx/xxx static URL freemarker = WordTest.class.getClassLoader().getResource("freemarker"); static String freemarkerPath = freemarker != null ? new File(freemarker.getFile()).getAbsolutePath() : new File("freemarker").getAbsolutePath(); //去除PDF水印文件 static URL aspose = WordTest.class.getClassLoader().getResource("freemarker"); static String asposePath = freemarker != null ? new File(freemarker.getFile()).getAbsolutePath() : new File("freemarker").getAbsolutePath(); public static void main(String[] args) { WordTest wordTest = new WordTest(); SimpleDateFormat sdf = new SimpleDateFormat("MMdd"); SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日"); SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日HH时mm分"); SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy.MM.dd"); Date date = new Date(); // 要填充的数据, 注意map的key要和word中${xxx}的xxx一致 Map<String, Object> dataMap = new HashMap<String, Object>(); List<Object> list = new ArrayList<Object>(); for (int i = 0; i < 10; i++) { WordUser word = new WordUser(); word.setImgEntityId(new Long(i)); word.setImgEntityName("目标" + i); word.setLeftUpLatitude(231.342 + i * 10); word.setLeftUpLongitude(234.32425 + i * 10); list.add(word); } dataMap.put("date", sdf.format(date)); dataMap.put("dateTime", sdf1.format(date)); dataMap.put("organicName", "国有控股"); dataMap.put("picCreateTime", sdf1.format(new Date())); dataMap.put("picCreateTime2", sdf2.format(new Date())); dataMap.put("picCreateTime3", sdf3.format(new Date())); dataMap.put("imgTypeName", "E-22战斗机"); dataMap.put("imgRootName", "无人机"); dataMap.put("imgEntity", "飞机、战斗机、歼-22、隐形战机"); dataMap.put("list", list); dataMap.put("station2", "先空下来"); dataMap.put("coordinate", "先空下来"); dataMap.put("thematicWords", "境外低轨侦察卫星"); dataMap.put("imgStr", wordTest.getImageStr2("http://47.93.82.37:8180/1.png")); // dataMap.put("imgStr", wordTest.getImageStr("/Users/macbook/Documents/1.png")); try { wordTest.exportSimpleWord(dataMap); } catch (Exception e) { e.printStackTrace(); } } public void exportSimpleWord(Map<String, Object> dataMap) throws Exception { // Configuration用于读取ftl文件 Configuration configuration = new Configuration(); configuration.setDefaultEncoding("utf-8"); /* * 以下是两种指定ftl文件所在目录路径的方式, 注意这两种方式都是 指定ftl文件所在目录的路径,而不是ftl文件的路径 */ // 指定路径的第一种方式(根据某个类的相对路径指定) // configuration.setClassForTemplateLoading(this.getClass(),""); // 指定路径的第二种方式,我的路径是C:/a.ftl configuration.setDirectoryForTemplateLoading(new File(freemarkerPath)); // 创建临时文件 // File outFile = File.createTempFile("pattern", ".docx"); // 输出文档路径及名称 File outFile = new File("/Users/macbook/Documents/test1.doc"); // 以utf-8的编码读取模版ftl文件 Template t = configuration.getTemplate("test4.ftl", "utf-8"); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240); t.process(dataMap, out); out.close(); // 删除临时文件 // outFile.delete(); // word文档转换成PDF String wordPath = "/Users/macbook/Documents/test1.doc"; doc2pdf(wordPath); } // 获取图片流 public String getImageStr2(String imgPath) { ByteArrayOutputStream data = new ByteArrayOutputStream(); try { URL url = new URL(imgPath); byte[] by = new byte[1024]; // 创建链接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(60 * 1000); InputStream is = conn.getInputStream(); // 将内容读取内存中 int len = -1; while ((len = is.read(by)) != -1) { data.write(by, 0, len); } // 关闭流 is.close(); } catch (Exception e) { e.printStackTrace(); } BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data.toByteArray()); } // word转PDF public void doc2pdf(String wordPath) { // if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生 // return; // } try { long old = System.currentTimeMillis(); File file = new File("/Users/macbook/Documents/test1.pdf"); // 新建一个空白pdf文档 FileOutputStream os = new FileOutputStream(file); Document doc = new Document(wordPath); // Address是将要被转化的word文档 doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, // EPUB, XPS, SWF 相互转换 long now = System.currentTimeMillis(); System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时 } catch (Exception e) { e.printStackTrace(); } } // 验证License 若不验证则转化出的pdf文档会有水印产生 public boolean getLicense() { boolean result = false; try { //InputStream is = WordTest.class.getClassLoader().getResourceAsStream("license.xml"); // license.xml应放在..\WebRoot\WEB-INF\classes路径下 InputStream is = new FileInputStream(asposePath+"/license2.xml"); License aposeLic = new License(); aposeLic.setLicense(is); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } } |
浏览器直接下载(get请求):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | @RequestMapping(value="/investigation/exportWord",method = RequestMethod.GET) @ResponseBody public void exportWord(HttpServletRequest request, HttpServletResponse response) { JSONObject result = new JSONObject(); Long imgPicId = Long.valueOf(request.getParameter("imgPicId")); // 要填充的数据, 注意map的key要和word中${xxx}的xxx一致 Map<String, Object> dataMap = exportSimpleWordService.exportSimpleWord(imgPicId); //获取图片类型名称作为文件名 String imgTypeName = (String) dataMap.get("imgTypeName"); // Configuration用于读取ftl文件 Configuration configuration = new Configuration(); configuration.setDefaultEncoding("utf-8"); // 指定路径我的路径是C:/a.ftl try { configuration.setDirectoryForTemplateLoading(new File(freemarkerPath));// 指定ftl所在目录,根据自己的改 response.setContentType("application/msword"); response.setHeader("Content-Disposition", "attachment;filename=\"" + new String((imgTypeName+"侦查要报.doc").getBytes("GBK"), "iso8859-1") + "\""); response.setCharacterEncoding("utf-8");// 此句非常关键,不然word文档全是乱码 PrintWriter out = response.getWriter(); Template t = configuration.getTemplate("investigation.ftl", "utf-8");// 以utf-8的编码读取ftl文件 t.process(dataMap, out); out.close(); } catch (Exception e) { logger.error("转换成word文档业务服务异常!", e); result.put("respCode", BaseRspConstants.RSP_CODE_FAILUR); result.put("respDesc", BaseRspConstants.RSP_DESC_FAILUR); } // return jsonObject; } |
链接:https://www.cnblogs.com/wylblogs/p/word.html