带有富文本数据如何导出word文档(使用mht模板)

一、制作mht模板

    使用word(不能用wps)制作好导出后想要的样子,并使用占位符填充,例如${NAME},设置好格式,另存为.mht格式的文件。之后用文本编辑器打开(我用的notepad++),检查一下(绑定语句可能会有‘=’或者空格),表格遍历需要手动加上<#list ··· as ···>,将文件放到项目中指定路径。

 

二、从数据库获取数据(dataMap)

   怎么获取就不说了, 一般用<String,Object>的Map接收,value值可能是String,或者是Map、List(模板中可能会有表格),也可能是富文本数据,一般来说富文本数据也是一串字符串,这里要注意从数据库取出来时要对数据进行处理(存入数据库时可能将单引号双引号替换为占位符,这个要具体结合项目和前台代码),富文本数据存入到List集合中(richHtmlList),之后还要进一步处理。

三、处理数据

    将富文本数据的集合进行组织处理,如果有img元素,需要将img元素分开进行单独处理

以下是部分代码,详细代码可以看原文档

public static void createDocFile(Map<String, Object> dataMap,List<String> richHtmlList,String templateName,HttpServletRequest request) throws Exception{  
    Template t = null;
    configuration.setDefaultEncoding("UTF-8");
    try{
    	t = configuration.getTemplate(templateName,"UTF-8");
	}catch(Exception e){
        e.printStackTrace();  
    }

    //富文本数据另行处理
    List<String> htmlContentList = new ArrayList<String>();
    List<String> htmlImageList = new ArrayList<String>();
    List<String> htmlImageRefList = new ArrayList<String>();
    for(String str : richHtmlList){
        htmlHandler(str,request,htmlContentList,htmlImageList,htmlImageRefList);
    }
    dataMap.put("htmlContentList",htmlContentList);
    dataMap.put("htmlImageList",htmlImageList);
    dataMap.put("htmlImageRefList",htmlImageRefList);

    //处理数据
    WordHtmlGeneratorHelper.handleAllObject(dataMap);
    	
    String fileName = "temp"+(int)(Math.random()*100000)+".doc";
    File f = new File(fileName);
    try {  
        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;  
}
public static void htmlHandler(String html,HttpServletRequest request,List<String> htmlContentList,List<String> htmlImageList,List<String> htmlImageRefList) throws Exception{
    RichHtmlHandler htmlHander = new RichHtmlHandler(html);
    htmlHander.setDocSrcLocationPrex(file:///C:/213792E5);
    htmlHander.setDocSrcParent("dwxfdzbgl_template.files");
    htmlHander.setNextPartId("01D1DDB9.9B20C780");
    htmlHander.setShapeidPrex("_x0000_i1025");
    htmlHander.setSpidPrex("_x0000_i");
    htmlHander.setTypeid("#_x0000_t75");
    htmlHander.handledHtml(request,true);
    //======handledDocBody block======\n
    String htmlString = htmlHandler.getHandledDocBodyBlock()+"\n";
    htmlContentList.add(htmlString);
    //======handledBase64Block==========
    StringBuffer htmlImageSb = new StringBuffer();
    if(htmlHandler.getDocBase64BlockResults()!=null
        &&htmlHandler.getDocBase64BlockResults().size()>0){
        for(String item : getDocBase64BlockResults()) {
             htmlImageSb.append(item+"\n");
        }    
    }
    htmlImageList.add(htmlImageSb.toString());
    //xmlimgHref
    StringBuffer htmlImageRefSb = new StringBuffer();
    if(htmlHandler.getXmlImgRefs()!=null && htmlHandler.getXmlImgRefs().size()>0){
        for(String item : htmlHandler.getXmlImgRefs()){
            htmlImageRefSb.append(item+"\n");
        }
    }
    htmlImageRefList.add(htmlImageRefSb.toString());
}

由于mht文件是采用的是“us-ascii”编码,所以dataMap中所有中文字符必须换成3Dus-asci,十进制Ascii码。

public static void handleAllObject(Map<String, Object> dataMap){
	//处理数据
    for (Map.Entry<String, Object> entry : dataMap.entrySet()){
    	Object item=entry.getValue();
    		
    	//判断object是否是primitive type 
    	if(isPrimitiveType(item.getClass())){
    		if(item.getClass().equals(String.class)){
    			item=WordHtmlGeneratorHelper.string2Ascii((String)item);
    			entry.setValue(item);
    		}
    	}else if(isCollection(item.getClass())){
    		for (Object itemobject : (Collection)item) {
    			WordHtmlGeneratorHelper.handleObject2Ascii(itemobject);
			}
    	}else if(isMap(item.getClass())){
            Collection<String> values = ((Map)item).values();
            for(String value : values){
                WordHtmlGeneratorHelper.handleObject2Ascii(value);
            }
        }else{
       		WordHtmlGeneratorHelper.handleObject2Ascii(item);
    	}
    }	
}

private static boolean isPrimitiveType(Class<?> clazz){
   	return clazz.isEnum() ||
	CharSequence.class.isAssignableFrom(clazz) ||
	Number.class.isAssignableFrom(clazz) ||
	Date.class.isAssignableFrom(clazz);	
}

private static boolean isCollection(Class<?> clazz){
   	return Collection.class.isAssignableFrom(clazz);
}

private static boolean isCollection(Class<?> clazz){
   	return Map.class.isAssignableFrom(clazz);
}

原文:http://www.cnblogs.com/liaofeifight/p/5484891.html

相关源代码:http://files.cnblogs.com/files/liaofeifight/word.rar

源代码中缺少对Map类型数据的处理,上面贴出的代码就是修改后的部分,

如果处理的数据较复杂,比如每个元素都是Map的List,则上面的方法无法处理后无效,博主的解决办法是在获取数据时直接调用string2Ascii()方法转换中文

public static String string2Ascii(String source){
	if(source==null || source==""){
		return null;
	}
	StringBuilder sb=new StringBuilder();
	
	char[] c=source.toCharArray();
	for(char item : c){
		String itemascii="";
		if(item>=19968 && item<40623){
			itemascii=itemascii="&#"+(item & 0xffff)+";";
		}else{
			itemascii=item+"";
		}
		sb.append(itemascii);
	}
	return sb.toString();	
}
	

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页