freemarker模板导出word

  1. 需要jar包:freemarker-2.3.19.jar
  2. 使用office 的word,另存xml格式,再修改后缀名为ftl,例如:scanResult.ftl
  3. 代码如下:
  4. package com.sbr.sdsp.tj.action;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    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 javax.annotation.Resource;
    import javax.servlet.ServletOutputStream;
    
    import org.apache.log4j.Logger;
    import org.apache.struts2.convention.annotation.Action;
    
    import com.sbr.platform.exception.SBRBusinessException;
    import com.sbr.sdp.platform.common.action.BaseAction;
    import com.sbr.sdsp.tj.model.SdspTjPort;
    import com.sbr.sdsp.tj.model.SdspTjTask;
    import com.sbr.sdsp.tj.model.SdspTjVuln;
    import com.sbr.sdsp.tj.service.ISdspTjPortService;
    import com.sbr.sdsp.tj.service.ISdspTjTaskService;
    import com.sbr.sdsp.tj.service.ISdspTjVulnService;
    import com.sbr.sdsp.util.HtmlRegexpUtil;
    import com.sbr.smwp.export.action.ExportWordAction;
    
    import freemarker.template.Configuration;
    import freemarker.template.DefaultObjectWrapper;
    import freemarker.template.Template;
    
    @Action(value = "sdspTjExportWord")
    public class SdspTjExportWordAction extends BaseAction{
    
    	private static final long serialVersionUID = 1L;
    	
    	private static final Logger LOGGER = Logger.getLogger(SdspTjExportWordAction.class);
    	
    	@Resource
    	private ISdspTjTaskService  sdspTjTaskService;
    	@Resource
    	private ISdspTjVulnService sdspTjVulnService;
    	@Resource
    	private ISdspTjPortService sdspTjPortService;
    	
    	private SdspTjTask sdspTjTask = new SdspTjTask();
    	
    	private String id;
    	
    	/**
         * 
         * @brief 根据ftl文件创建word模板
         * @return File
         * @author    
         * @date      2016-7-27
         * @copyright 
          */
    	public static File createDoc(Map<?, ?> dataMap, String type) throws Exception {
    		Configuration cfg = new Configuration();
    		cfg.setDefaultEncoding("utf-8");
    		cfg.setClassForTemplateLoading(ExportWordAction.class, "/");
    		cfg.setObjectWrapper(new DefaultObjectWrapper());
    		
    		String name = "temp" + (int) (Math.random() * 100000) + ".doc";
    		File f = new File(name);
    		Template t = cfg.getTemplate(type + ".ftl", "utf-8");
    		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;
    	}
    	
    	/**
         * 
         * @brief 导出任务扫描结果的word
         * @return void
         * @author   
         * @date      2016-7-27
         * @copyright 
          */
    	public void ExportResults() {
    		// 任务
    		sdspTjTask = sdspTjTaskService.retrieveSdspTjTaskById(id);
    		// 任务扫描对应的漏洞列表
    		List<SdspTjVuln> vulns = sdspTjVulnService.retrieveSdspTjVulnsByTaskId(id);
    		vulns = filterHtmlTag(vulns);
    		// 任务扫描对应的端口列表
    		List<SdspTjPort> ports = sdspTjPortService.retrieveSdspTjPortsByTaskId(id);
    		//查询scanner_service表获取端口类型和描述
    		ports = translateToScanPortList(ports);
    		// 漏洞数
    		Map<String, Integer> vulnMap = sdspTjVulnService.countVulnByTaskId(id);
    		// 端口数
    		int portCount = sdspTjPortService.countPortByTaskId(id);
    		// 得到填充数据
    		Map<String, Object> dataMap = new HashMap<String, Object>();
    		// 封装word数据
    		packageData(dataMap, sdspTjTask.getTaskName(),
    				sdspTjTask.getSysOrganization().getName(), sdspTjTask.getTargetIp(), vulns,
    				ports, vulnMap, portCount);
    		//导出word
    		exportWord(dataMap);
    	}
    	
    	/**
         * 
         * @brief 封装导出word数据
         * @return void
         * @author    
         * @date      2016-7-28
         * @copyright 
          */
    	private void packageData(Map<String, Object> dataMap, String taskName,
    			String orgName, String targetIP, List<SdspTjVuln> vulns,
    			List<SdspTjPort> ports, Map<String, Integer> vulnMap, int portCount) {
    		dataMap.put("taskName", taskName);
    		dataMap.put("orgName", orgName);
    		dataMap.put("targetIP", targetIP);
    		dataMap.put("vulns", vulns);
    		dataMap.put("ports", ports);
    		dataMap.putAll(vulnMap);
    		dataMap.put("portCount", portCount);
    		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
    		dataMap.put("createDate", sdf.format(new Date()).toString());
    	}
    	
    	/**
         * 
         * @brief 导出word
         * @return void
         * @author    
         * @date      2016-7-28
         * @copyright
          */
    	private void exportWord(Map<String, Object> dataMap){
    		File file = null;
    		InputStream fis = null;
    		ServletOutputStream out = null;
    		try {
    			file = createDoc(dataMap, "scanResult");
    			fis = new FileInputStream(file);
    			getResponse().setCharacterEncoding("utf-8");
    			getResponse().setContentType("application/msword");
    			// 设置浏览器下载附件名称
    			getResponse().addHeader("Content-Disposition","attachment;filename="
    							+ new String((sdspTjTask.getTaskName()+"系统漏洞扫描结果").getBytes("gbk"),"ISO8859-1") + ".doc");
    			out = getResponse().getOutputStream();
    			byte[] buffer = new byte[1024];
    			int len = -1;
    			while ((len = fis.read(buffer)) != -1) {
    				out.write(buffer, 0, len);
    			}
    			out.flush();
    		} catch (Exception e) {
    			LOGGER.error("扫描结果导出word失败!");
    			throw new SBRBusinessException("扫描结果导出word失败!原因是:"+e);
    		} finally {
    				try {
    					if (fis != null){
    						fis.close();
    					}
    					if (out != null)
    						out.close();
    					if (file != null)
    						file.delete(); // 删除临时文件
    				} catch (IOException e) {
    					LOGGER.error("关闭文件流失败!");
    					throw new SBRBusinessException("关闭文件流失败!原因是:"+e);
    				}
    			
    		}
    	}
    	
    	/**
         * 
         * @brief 过滤html标签
         * @return void
         * @author   
         * @date      2016-7-28
         * @copyright
          */
    	private List<SdspTjVuln> filterHtmlTag(List<SdspTjVuln> vulns){
    		if(vulns == null || vulns.size() <= 0){
    			return new ArrayList<SdspTjVuln>();
    		}
    		List<SdspTjVuln> list = new ArrayList<SdspTjVuln>();
    		for (SdspTjVuln vuln : vulns) {
            	String remedy = HtmlRegexpUtil.filterHtml(vuln.getRemedy());
            	remedy = replaceTag(remedy);
            	vuln.setRemedy(remedy);
            	String desc = HtmlRegexpUtil.filterHtml(vuln.getDescription());
            	desc = replaceTag(desc);
            	vuln.setDescription(desc);
            	vuln.setRiskLevel(transRiskLevel(vuln.getVulnSeverity()));
            	SdspTjVuln v = sdspTjVulnService.getscannerVuln(vuln.getId(), vuln.getVulnId());
            	vuln.setNodeName(v.getNodeName());
            	vuln.setShortDesc(v.getShortDesc());
            	list.add(vuln);
    		}
    		return list;
    	}
    	
    	/**
         * 
         * @brief 危险级别
         * @return String
         * @author
         * @date      2016-7-28
         * @copyright
          */
    	private String transRiskLevel(int riskLevel){
    		if(riskLevel == 3){
        		return"高危";
        	}else if(riskLevel == 2){
        		return"中危";
        	}else if(riskLevel == 1){
        		return"低危";
        	}else if(riskLevel == 4){
        		return"信息";
        	}else{
        		return"未知";
        	}
    	}
    	
    	/**
         * 
         * @brief 获取端口类型和描述
         * @return List<SdspTjPort> 端口服务列表
         * @author
         * @date      2016-8-1
         * @copyright
          */
    	private List<SdspTjPort> translateToScanPortList(List<SdspTjPort> ports){
    		if(ports == null || ports.size() <= 0){
    			return new ArrayList<SdspTjPort>();
    		}
    		List<SdspTjPort> list = new ArrayList<SdspTjPort>();
    		for (SdspTjPort port : ports) {
    			SdspTjPort p = sdspTjPortService.getScanPortById(port.getId());
    			if(p != null){
    				list.add(p);
    			}
    		}
    		return list;
    	}
    	
    	/**
         * 
         * @brief 过滤特殊符号
         * @return String 过滤后的结果返回
         * @param input 字符串
         * @author
         * @date      2016-7-28
         * @copyright
          */
    	public String replaceTag(String input) {
    		if (!hasSpecialChars(input)) {
    			return input;
    		}
    		StringBuffer filtered = new StringBuffer(input.length());
    		char c;
    		for (int i = 0; i <= input.length() - 1; i++) {
    			c = input.charAt(i);
    			switch (c) {
    			case '<':
    				filtered.append("&lt;");
    				break;
    			case '>':
    				filtered.append("&gt;");
    				break;
    			case '"':
    				filtered.append("&quot;");
    				break;
    			case '&':
    				filtered.append("&amp;");
    				break;
    			default:
    				filtered.append(c);
    			}
    		}
    		return (filtered.toString());
    	}
    
    	/**
         * 
         * @brief 判断标记是否存在
         * @return boolean
         * @param input 字符串
         * @author
         * @date      2016-7-28
         * @copyright
          */
    	public boolean hasSpecialChars(String input) {
    		boolean flag = false;
    		if ((input != null) && (input.length() > 0)) {
    			char c;
    			char c1;
    			for (int i = 0; i <= input.length() - 2; i++) {
    				c = input.charAt(i);
    				c1 = input.charAt(i+1);
    				String str = String.valueOf(c)+String.valueOf(c1);
    				if(!"&#47".contains(str)){//   &#47:/   不参与过滤
    					switch (c) {
    					case '>':
    						flag = true;
    						break;
    					case '<':
    						flag = true;
    						break;
    					case '"':
    						flag = true;
    						break;
    					case '&':
    						flag = true;
    						break;
    					}
    				}
    			}
    		}
    		return flag;
    	}
    	
    	
    	@Override
    	public Object getModel() {
    		return sdspTjTask;
    	}
    
    	public String getId() {
    		return id;
    	}
    
    	public void setId(String id) {
    		this.id = id;
    	}
    	
    
    }
    

word表格数据不支持html代码,需要过滤掉,导出的word才能正常打开

过滤类如下:

package com.sbr.sdsp.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Title: HTML相关的正则表达式工具类
 * Description: 包括过滤HTML标记,转换HTML标记,替换特定HTML标记
 */
public class HtmlRegexpUtil {
	private final static String regxpForHtml = "<([^>]*)>"; // 过滤所有以<开头以>结尾的标签

	private final static String regxpForImgTag = "<\\s*img\\s+([^>]*)\\s*>"; // 找出IMG标签

	private final static String regxpForImaTagSrcAttrib = "src=\"([^\"]+)\""; // 找出IMG标签的SRC属性

	/**  
     *   
     */
	public HtmlRegexpUtil() {
		
	}

	/**
	 * 
	 * 基本功能:替换标记以正常显示
	 * <p>
	 * 
	 * @param input
	 * @return String
	 */
	public String replaceTag(String input) {
		if (!hasSpecialChars(input)) {
			return input;
		}
		StringBuffer filtered = new StringBuffer(input.length());
		char c;
		for (int i = 0; i <= input.length() - 1; i++) {
			c = input.charAt(i);
			switch (c) {
			case '<':
				filtered.append("&lt;");
				break;
			case '>':
				filtered.append("&gt;");
				break;
			case '"':
				filtered.append("&quot;");
				break;
			case '&':
				filtered.append("&amp;");
				break;
			default:
				filtered.append(c);
			}

		}
		return (filtered.toString());
	}

	/**
	 * 
	 * 基本功能:判断标记是否存在
	 * <p>
	 * 
	 * @param input
	 * @return boolean
	 */
	public boolean hasSpecialChars(String input) {
		boolean flag = false;
		if ((input != null) && (input.length() > 0)) {
			char c;
			for (int i = 0; i <= input.length() - 1; i++) {
				c = input.charAt(i);
				switch (c) {
				case '>':
					flag = true;
					break;
				case '<':
					flag = true;
					break;
				case '"':
					flag = true;
					break;
				case '&':
					flag = true;
					break;
				}
			}
		}
		return flag;
	}

	/**
	 * 
	 * 基本功能:过滤所有以"<"开头以">"结尾的标签
	 * <p>
	 * 
	 * @param str
	 * @return String
	 */
	public static String filterHtml(String str) {
		Pattern pattern = Pattern.compile(regxpForHtml);
		Matcher matcher = pattern.matcher(str);
		StringBuffer sb = new StringBuffer();
		boolean result1 = matcher.find();
		while (result1) {
			matcher.appendReplacement(sb, "");
			result1 = matcher.find();
		}
		matcher.appendTail(sb);
		return sb.toString();
	}

	/**
	 * 
	 * 基本功能:过滤指定标签
	 * <p>
	 * 
	 * @param str
	 * @param tag
	 *            指定标签
	 * @return String
	 */
	public static String filterHtmlTag(String str, String tag) {
		String regxp = "<\\s*" + tag + "\\s+([^>]*)\\s*>";
		Pattern pattern = Pattern.compile(regxp);
		Matcher matcher = pattern.matcher(str);
		StringBuffer sb = new StringBuffer();
		boolean result1 = matcher.find();
		while (result1) {
			matcher.appendReplacement(sb, "");
			result1 = matcher.find();
		}
		matcher.appendTail(sb);
		return sb.toString();
	}

	/**
	 * 
	 * 基本功能:替换指定的标签
	 * <p>
	 * 
	 * @param str
	 * @param beforeTag
	 *            要替换的标签
	 * @param tagAttrib
	 *            要替换的标签属性值
	 * @param startTag
	 *            新标签开始标记
	 * @param endTag
	 *            新标签结束标记
	 * @return String
	 * @如:替换img标签的src属性值为[img]属性值[/img]
	 */
	public static String replaceHtmlTag(String str, String beforeTag,
			String tagAttrib, String startTag, String endTag) {
		String regxpForTag = "<\\s*" + beforeTag + "\\s+([^>]*)\\s*>";
		String regxpForTagAttrib = tagAttrib + "=\"([^\"]+)\"";
		Pattern patternForTag = Pattern.compile(regxpForTag);
		Pattern patternForAttrib = Pattern.compile(regxpForTagAttrib);
		Matcher matcherForTag = patternForTag.matcher(str);
		StringBuffer sb = new StringBuffer();
		boolean result = matcherForTag.find();
		while (result) {
			StringBuffer sbreplace = new StringBuffer();
			Matcher matcherForAttrib = patternForAttrib.matcher(matcherForTag.group(1));
			if (matcherForAttrib.find()) {
				matcherForAttrib.appendReplacement(sbreplace, startTag + matcherForAttrib.group(1) + endTag);
			}
			matcherForTag.appendReplacement(sb, sbreplace.toString());
			result = matcherForTag.find();
		}
		matcherForTag.appendTail(sb);
		return sb.toString();
	}
}

 

转载于:https://my.oschina.net/panhongguang/blog/725883

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值