java 根据freemarker模板导出word

freemarker导出word 文档list 集合遍历数据和图片

技术: freemarker 技术---我们word 高级版本(ftl 的制作)

1 首先要准备ftl 文档

打开word 编辑,有图片的话插入一张图片,变为下面形式(注意,下面为表格插入,一行一列)

然后将word 另存为xml  文档   -- word.xml    注意:(${}可能被分开或换行,最好是生成xml之前不加${},生成xml文档之后再补上${})

打开xml 文档,下面我们就更改四处,

一 加入 <w:tr>前<#list list as list>    第一个list 不能变  第二个list 为变量名  第三个list 为别名

二 将${fieldname}  改为${list.fieldname}

三 将${fieldname} 改为${list.fieldname}

四 </w:tr>后加入</#list>

<#list list as list>
                        <w:tr>
                            <w:tblPrEx>
                                <w:tblBorders>
                                 .......
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia"/>
                                            <w:lang w:val="en-US"
                                                    w:eastAsia="zh-CN"/>
                                        </w:rPr>
                                        <w:t>${list.fieldname}</w:t>
                                    </w:r>
                                </w:p>
                               .......
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia"/>
                                            <w:lang w:val="en-US"
                                                    w:eastAsia="zh-CN"/>
                                        </w:rPr>
                                        <w:t>${list.field}</w:t>
                                    </w:r>
                                </w:p>
                                <w:p>
                                    
                                </w:p>
                            </w:tc>
                        </w:tr>
                    </#list>

这是freemarker循环行的处理语法;

将改好的xml 保存,如果notepad++报错不用理会,将xml 改为ftl 文件,就得到我们需要的ftl了,    编译后的不要用word打开

2 java 代码的实现

引入jar 包


 <properties>
    <!--freemarker-->
    <freemarker.version>2.3.23</freemarker.version>
    
  </properties>
  <dependencies>
  
    <!--freemarker-->
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>${freemarker.version}</version>
    </dependency>

 

导出word工具类代码:
package com.linewell.sjj;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
 
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 
 public class WordUtils {
      //配置信息,代码本身写的还是很可读的,就不过多注解了  
     private static Configuration configuration = null;  
     //这里注意的是利用WordUtils的类加载器动态获得模板文件的位置  																			 
     private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/templates/doc";  
     //private static final String templateFolder = "F:\\hebei4\\jgj\\WebRoot\\WEB-INF\\templates\\doc";  
     static {  
         configuration = new Configuration();  
         configuration.setDefaultEncoding("utf-8");  
         try {  
             configuration.setDirectoryForTemplateLoading(new File(templateFolder));  
         } catch (IOException e) {  
             e.printStackTrace();  
         }  
    }  
   
     private WordUtils() {  
         throw new AssertionError();  
     }  
   
     public static void exportMillCertificateWord( HttpServletResponse response,Map map,String title,String ftlFile) throws IOException {  
         
    	 Template freemarkerTemplate = configuration.getTemplate(ftlFile);  
         File file = null;  
         InputStream fin = null;  
         ServletOutputStream out = null;  
         try {  
             // 调用工具类的createDoc方法生成Word文档  
             file = createDoc(map,freemarkerTemplate);  
             fin = new FileInputStream(file);  
   
             response.setCharacterEncoding("utf-8");  
             response.setContentType("application/msword");  
             // 设置浏览器以下载的方式处理该文件名  
             String fileName = title + ".doc";  
             response.setHeader("Content-Disposition", "attachment;filename="  
                     .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));  
   
             out = response.getOutputStream();  
             byte[] buffer = new byte[512];  // 缓冲区  
             int bytesToRead = -1;  
             // 通过循环将读入的Word文件的内容输出到浏览器中  
             while((bytesToRead = fin.read(buffer)) != -1) {  
                 out.write(buffer, 0, bytesToRead);  
             }  
         } finally {  
             if(fin != null) fin.close();  
             if(out != null) out.close();  
             if(file != null) file.delete(); // 删除临时文件  
         }  
     }  
     
 public static void exportMillCertificateWord2( Map dataMap,String title,String ftlFile) throws IOException {  
         
    	 Template freemarkerTemplate = configuration.getTemplate(ftlFile);  
         File file = null;  
         InputStream fin = null;  
         OutputStream out = null;  
        try {  
             // 调用工具类的createDoc方法生成Word文档  
             file = createDoc(dataMap,freemarkerTemplate);  
             fin = new FileInputStream(file);  
   
				/*
				 * response.setCharacterEncoding("utf-8");
				 * response.setContentType("application/msword"); // 设置浏览器以下载的方式处理该文件名 String
				 * fileName = title + ".doc"; response.setHeader("Content-Disposition",
				 * "attachment;filename=" .concat(String.valueOf(URLEncoder.encode(fileName,
				 * "UTF-8"))));
				 */
             out = new FileOutputStream(file);
             //out = OutputStream();  
             byte[] buffer = new byte[512];  // 缓冲区  
             int bytesToRead = -1;  
             // 通过循环将读入的Word文件的内容输出到浏览器中  
             while((bytesToRead = fin.read(buffer)) != -1) {  
                 out.write(buffer, 0, bytesToRead);  
             }  
         } finally {  
             if(fin != null) fin.close();  
             if(out != null) out.close();  
             if(file != null) file.delete(); // 删除临时文件  
         }  
     }  
   

	private static File createDoc(Map<?, ?> dataMap, Template template) {  
         String name =  templateFolder+"/后置现场审查表.doc";  
		//String name = "f://后置现场审查表.doc";  
         File f = new File(name);  
         Template t = template;
         try {  
             // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开  
             Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");  
             t.process(dataMap, w);  
             w.close();  
         } catch (Exception ex) {  
             ex.printStackTrace();  
             throw new RuntimeException(ex);  
         }  
         return f;  
     }  
}

 调用方法实例:注意(map中的key要与ftl文件中变量对应上,图片必须转成Base64格式)

private static String document="hzxcscb.ftl";



Map dataMap = new HashMap(); dataMap.put("txtEnterpriseName",txtEnterpriseName ); dataMap.put("zs", zs); dataMap.put("txtzsbh", txtzsbh); dataMap.put("rr", txtEnterpriseName); dataMap.put("qq", zs); dataMap.put("qymc", qymc); dataMap.put("qymcqkms", qymcqkms); dataMap.put("qydz", qydz); dataMap.put("qydzqkms", qydzqkms); dataMap.put("zsmx", zsmx); dataMap.put("zsmxqkms", zsmxqkms); dataMap.put("qysfcysczt", qysfcysczt); dataMap.put("qysfcyscztqkms", qysfcyscztqkms); dataMap.put("hcjl", hcjl); dataMap.put("hcjlqkms", hcjlqkms); dataMap.put("qyfzr", qyfzr); dataMap.put("scy", scy); dataMap.put("xzry", xzry); dataMap.put("gcy", ""); dataMap.put("list", mapList); try { WordUtils.exportMillCertificateWord(response,dataMap,"后置现场审查表",document); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }

 ftl文件中的图片处理:(多张图片的话,标红的部分必须动态)

 

<w:pict>
	                        <w:binData w:name="${"wordml://"+list_index+".jpg"}">${list.ss!}</w:binData>                  
							<v:shape id="${list_index}" o:spt="75" alt="" type="${list_index}" style="height:119.5pt;width:79.7pt;" filled="f" o:preferrelative="t" stroked="f" coordsize="21600,21600">                          <v:path/>                          <v:fill on="f" focussize="0,0"/>                          <v:stroke on="f"/>                          
							<v:imagedata src="${"wordml://"+list_index+".jpg"}" o:title="${list_index}"/>                          
							<o:lock v:ext="edit" aspectratio="t"/>                          
							<w10:wrap type="none"/>                          
							<w10:anchorlock/>                        
							</v:shape>                      
						</w:pict>

  结束。

 

 

 











 

posted @ 2021-08-09 17:23  孤狼奋战  阅读(129)  评论(0编辑  收藏  举报