java 模板技术动态导出 word

1.新增一个word输入一行字
2.保存,另存为xml格式,在网上找xml格式化,格式化一下保存。(xml很乱建议格式化一下不格式化也可以)
3.把xml文件放在项目中的某个位置。我放在 root-res下(ceshi.xml)
4.服务器后端代码 确定把map输出在哪一个xml里面
5.xml中使用${}语法获取传过来的值

1-3步略过不演示了 贴一张我的word效果
在这里插入图片描述

4.服务端代码

 String mypath = this.getServletConfig().getServletContext().getRealPath("/");
            String path = mypath + "res\\ceshi.xml";//导出 excel
            String fileName = "";
            Date mydate = new Date();//日期
            fileName = MT.f(mydate) + "我要测试一下.docx";
            String userAgent = request.getHeader("User-Agent");

            boolean isMSIE = ((userAgent != null && userAgent.indexOf("MSIE") != -1) || (null != userAgent && -1 != userAgent.indexOf("like Gecko")));
            //传到xml的map集合
            List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
            for (int i = 0; i <5 ; i++) {
    
    
                //单个map  xml中遍历的单个
                HashMap<String, Object> map = new HashMap<>();
                map.put("one", i + "测试");
                map.put("two","第几页?"+i+"页");
                listmap.add(map);
            }



            if (isMSIE) {
    
    
                fileName = new String(fileName.getBytes("GBK"), "ISO8859-1");
            } else {
    
    
                fileName = new String(fileName.getBytes("UTF8"), "ISO8859-1");
            }


            response.setContentType("APPLICATION/OCTET-STREAM");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

            Map<String, Object> map = new HashMap<String, Object>();

            map.put("listmap", listmap);
            String html = FreeMarkerUtils.parseText(path, map);
            html = FreeMarkerTransfer.getHtmlFromTmplString(html, map);
            OutputStream os = response.getOutputStream();
            byte b[] = html.getBytes("UTF-8");// 只能输出byte数组,所以将字符串变为byte数组

            os.write(b);
            os.flush();
            os.close();

FreeMarkUtils

package 你的包路径;

import java.io.File;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

public class FreeMarkerUtils {
    
    
	/**
     * 根据模版名称和实际数据解析生成html文本
     * @param filePath 模版文件完整路径
     * @param data 数据
     * @return html文本
     */
    public static String parseText(String filePath, Map data) {
    
    

        if (StringUtils.isEmpty(filePath)) {
    
    
            return "<font color='#F00'>Template not found.</font>";
        }

        File file = new File(filePath);

        FreeMarkerTransfer trans = new FreeMarkerTransfer(file.getParent());
        trans.setParams(data);
        return trans.write2Str(file.getName());
    }
}

FreeMarkerTransfer

package 包路径;

import java.io.File;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;

/**
 * 执行指定的freemarker模板,并返回html结果。
 * 
 * @author 灵活的的胖子
 */
public class FreeMarkerTransfer {
    
    
    
    private static final Map<String, Configuration> CONFIG_MAP = new ConcurrentHashMap<String, Configuration>();
    
    /**
     * 需要传递给FreeMarker的参数
     */
    private Map<Object, Object> params = new HashMap<Object, Object>();
    
    /**
     * freemarker模板所在的目录
     */
    private String templateDir = "";
    
    /**
     * @param tmplDir 模板文件的路径
     */
    public FreeMarkerTransfer(String tmplDir) {
    
    
        templateDir = tmplDir;
    }
    
    /**
     * 增加需要传递给模板的变量,这些变量可以直接在模板中调用
     * 
     * @param name 变量的名称。
     * @param var 变量对应的对象。
     */
    public void addVariable(String name , Object var) {
    
    
        params.put(name, var);
    }
    
    /**
     * 将freemarker文件的执行结果输出到writer对象中
     * 
     * @param writer 输出
     * @param template freemarker文件
     */
    public void write(Writer writer , String template) {
    
    
        try {
    
    
            getConfig(templateDir).getTemplate(template).process(params, writer);
        } catch (Exception e) {
    
    
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    /**
     * 将freemarker文件的执行结果输出成
     * 
     * @param template 模板名称
     * @return freemarker文件的执行结果
     */
    public String write2Str(String template) {
    
    
        StringWriter writer = new StringWriter();
        this.write(writer, template);
        return writer.toString();
    }
    
    /**
     * 设置传递给FreeMarker的参数。
     * 
     * @param bean 传递给FreeMarker的参数
     */
    public void setParams(Map<Object, Object> bean) {
    
    
        this.params = bean;
    }
    
    /**
     * 根据指定目录从缓存中取得Configuration对象,如果缓存中不存在,则重新创建。
     * 
     * @param tmplDir ftl模板所在的路径(先对于操作系统的绝对路径)。
     * @return 取得FreeMarker的配置文件
     * @throws Exception 构造config对象时产生的错误
     */
    private static Configuration getConfig(String tmplDir) throws Exception {
    
    
        Configuration config = CONFIG_MAP.get(tmplDir);
        if (config != null) {
    
    
            return config;
        }
        
        config = new Configuration();
        config.setObjectWrapper(new DefaultObjectWrapper());
        config.setDirectoryForTemplateLoading(new File(tmplDir));
//        config.setEncoding(Locale.CHINA, "UTF-8");
        config.setDefaultEncoding("UTF-8");
        CONFIG_MAP.put(tmplDir, config);
        
        return config;
    }

    /**
     * 根据模板内容和实际数据解析生成html文本
     * @param ftlContent 模板内容
     * @param data 数据
     * @return html文本
     */
    public static String getHtmlFromTmplString(String ftlContent, Map data) {
    
    
        if(!ftlContent.contains("<html xmlns:v='urn:schemas-microsoft-com") && !ftlContent.contains("<?xml")){
    
    
            StringBuffer head = new StringBuffer(
                    "<html xmlns:v='urn:schemas-microsoft-com:vml'xmlns:o='urn:schemas-microsoft-com:office:office'xmlns:w='urn:schemas-microsoft-com:office:word'xmlns:m='http://schemas.microsoft.com/office/2004/12/omml'xmlns='http://www.w3.org/TR/REC-html40'  xmlns='http://www.w3.org/1999/xhtml' > ");
            head.append("<head>");
            head.append(" <!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View><w:TrackMoves>false</w:TrackMoves><w:TrackFormatting/><w:ValidateAgainstSchemas/><w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid><w:IgnoreMixedContent>false</w:IgnoreMixedContent><w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText><w:DoNotPromoteQF/><w:LidThemeOther>EN-US</w:LidThemeOther><w:LidThemeAsian>ZH-CN</w:LidThemeAsian><w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript><w:Compatibility><w:BreakWrappedTables/><w:SnapToGridInCell/><w:WrapTextWithPunct/><w:UseAsianBreakRules/><w:DontGrowAutofit/><w:SplitPgBreakAndParaMark/><w:DontVertAlignCellWithSp/><w:DontBreakConstrainedForcedTables/><w:DontVertAlignInTxbx/><w:Word11KerningPairs/><w:CachedColBalance/><w:UseFELayout/></w:Compatibility><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><m:mathPr><m:mathFont m:val='Cambria Math'/><m:brkBin m:val='before'/><m:brkBinSub m:val='--'/><m:smallFrac m:val='off'/><m:dispDef/><m:lMargin m:val='0'/> <m:rMargin m:val='0'/><m:defJc m:val='centerGroup'/><m:wrapIndent m:val='1440'/><m:intLim m:val='subSup'/><m:naryLim m:val='undOvr'/></m:mathPr></w:WordDocument></xml><![endif]-->");
            head.append("<meta charset='UTF-8'>");
            head.append("<meta name=ProgId content=Word.Document>");
            head.append("<meta name=Generator content='Microsoft Word 14'>");
            head.append("<meta name=Originator content='Microsoft Word 14'>");
            head.append("</head>");
            head.append("<body style='tab-interval: 21pt; text-justify-trim: punctuation;'>");
            ftlContent = head.toString() + ftlContent + "</body></html>";
        }
        // 设置一个字符串模板加载器
        StringTemplateLoader stringLoader = new StringTemplateLoader();
        Configuration STRING_CONFIG = new Configuration();
        STRING_CONFIG.setDefaultEncoding("UTF-8");
        STRING_CONFIG.setTemplateLoader(stringLoader);
        stringLoader.putTemplate("", ftlContent);
        StringWriter writer = new StringWriter();
        try {
    
    
            // 获取匿名模板
            STRING_CONFIG.getTemplate("").process(data, writer);
        } catch (Exception e) {
    
    
            throw new RuntimeException(e.getMessage(), e);
        }
        return writer.toString();
    }

}

5.xml中获取方式

<w:body>
    <wx:sect>
    <w:p/>
        <!--遍历listmap  固定格式 java后端传给map的集合名称 listmap   as后面自定义名称 mymap.one 与之对应-->
         <#list listmap as mymap>
    <w:p>
        <w:pPr>
            <w:rPr>
                <w:rFonts w:fareast="宋体" w:hint="default"/>
                <w:lang w:val="EN-US" w:fareast="ZH-CN"/>
            </w:rPr>
        </w:pPr>
        <w:r>
            <w:rPr>
                <w:rFonts w:hint="fareast"/>
                <w:lang w:val="EN-US" w:fareast="ZH-CN"/>
            </w:rPr>

            <w:t>这是第几页${mymap.one}${mymap.two}</w:t>
        </w:r>
    </w:p>
        <!--map集合是否有下一个  有的话就加一个换页符-->
        <#if mymap_has_next>
        <w:p>
            <w:pPr>
                <w:autoSpaceDE w:val="0"/>
                <w:autoSpaceDN w:val="0"/>
                <w:adjustRightInd w:val="0"/>
                <w:ind w:right="-20"/>
                <w:jc w:val="left"/>
                <w:rPr>
                    <w:sz w:val="24"/>
                </w:rPr>
            </w:pPr>
            <w:r>
                <w:rPr>
                    <w:sz w:val="24"/>
                </w:rPr>
                <w:br w:type="page"/>
            </w:r>
        </w:p>
    </#if>
        </#list>
        <w:sectPr>

效果

在这里插入图片描述
在这里插入图片描述
省略几页
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lzq_20120119/article/details/115045004