利用JavaScript 实现Word简单导出功能
最近项目中需要一个word导出的功能,上网查了下相关资料,基本上都是基于Jacob或者POI等组件来实现,需要相关jar以及环境配置,如果不好好研究下,不是那么好实现,这里介绍一种单纯利用javaScript就可以实现Word导出的方法。
在项目中,我需要在流程结束时,把评审表导出成word。但在导出前用户可以先预览一下评审表,如下为评审表Web页面(到时候要导出的即为这个页面内容)
因为评审表有word的模版,所以我把word模版另存为一个html格式(主要是保留样式),再改成jsp,然后拿这个jsp文件作为预览页面的开发基础,在此页面进行数据获取之后就可以通过“导出word”按钮来进行导出了。
导出后的效果如下图。(基本上一模一样)
下面说说具体的代码以及实现方式
2个主要文件:WordExporter.js和word_out.jsp(都很小,js有500行,jsp有200行)
按钮的代码:
<input id="export" type="button" style="position: absolute; right: 20px; top: 23px;" value="导出Word"></input>//(有个id就行了,后面为他绑定个事件而已)
WordExporter.js:主要是构造函数、导出事件以及基本的过滤器等等。引用此插件之后,只要在业务逻辑js文件里进行初始化构造函数即可,上代码:
var wordputter = new $WordExporter("export",{//用于触发事件的元素id action : "../exportWord/word_out.jsp", //必须 提交地址
wordName :question_title,//必须 导出word的名称 默认名称:未定义.doc
outDiv : "body", //必须 要导出代码块父容器对象或ID 要导出DIV
cssLinkId : "" , //非必须 有默认css 要导出word格式LinkId;
cssString :"",//非必须 有默认css,同时设置该属性和cssLinkId,此属性优先 显式传入的css内容
data:[], //非必须附带提交到后台处理变量列表.格式:[{name:param,value:value}...]
filter:function(dataStr){return dataStr;} //过滤器扩展接口 ,同时 必须有返回值
});
通过上面的初始化基本上就可以把web导出为word了。如果有模版的,可以像我上面说的导出为html 再开发,这样会保留基本样式。如果样式比较少可以直接写在cssString参数后面,如果样式比较多的话,为了不造成混乱,可以把那些样式剪切到一个css文件里,然后在word_out.jsp里面进行通过读写css文件里面的内容来实现样式。上代码:
//获取部属应用系统的绝对路径
EnvironmentUtil environmentUtil = EnvironmentUtil.getInstance();
String storePath = environmentUtil.getAppPath()+"inms/exportWord/wordCss.css";
//实例化字符串缓冲类,大部分情况比StringBuffer快,比String拼接更快
StringBuilder builder = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(storePath)));
char[] chars = new char[4096];
int length = 0;
while (0 < (length = reader.read(chars))) {
builder.append(chars, 0, length);
}
} finally {
try {
if (reader != null) reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
这里还有一个比较重点的就是过滤器,WordExporter.js里面已经有一些基本的过滤了,像我在开发预览页面的时候遇到一些隐藏域或者一些不是隐藏域但是是一些和文档不相关的按钮,比如我上面说的触发事件的按钮,如果没有进行过滤,在导出word之后,有值的隐藏域会把值也导出来(但这可能不是我们想要的)而遇到按钮什么的,就会导出为undefined,这时候正则表达式就派上用场了,正则表达式很强大,效率也高,但是要想学好却很难(本人菜鸟一只,勿喷!)
举个很简单例子:
<input id=”test” type=”hidden” style=”left:10px;display:none;right:10px”><input>
str = str.replace(/<INPUT[^>]*type=\”hidden\”[^>]*>/ig,””)。
str = str.replace(/<INPUT[^>]*style=\”[^>]*display:none[^>]*\”[^>]*>/ig,"");
解释:前后2个/为正则定界符,即表达式开始与结束。[^>]:非“>”的任意字符。*:匹配前面字符0次或者多次。\”:匹配双引号。i:忽略大小写。g:全局匹配。
这2句就可以把隐藏类型的input元素替换成””,这样在导出时就不会出现上面的情况了。大家也可以下载正则测试工具,挺好用的。
当然也可以用js或者就jquery来过滤,方法很多,看个人选择了。
最后一步就是执行下载的代码:
response.setHeader("Content-disposition","attachment;filename=\""+new String((wordName+".doc").getBytes("gb2312"),"ISO8859-1") + "\"");
作为附件下载,文件名为初始化时传进来的名称,并进行编码设置。