HTML转word主要用freemarker模板来处理,如果只是导出文字内容,那很好处理。但是带图片了就比较麻烦。
步骤大概是:在前台,我们把echart图转为base64形式传到后台(echart图是由canvas写的,所以用canvas的一个方法可以直接将图转为base64,这样的话问题就来了,base64长度很长,我们直接用get方法提交的话参数限制,提交会不成功。可是用post方法必须要有返回值,我们想点击按钮直接弹出下载选择框就成为泡影了,下面是我借鉴别人的一个方法)
前台代码:
$.post("<%=path%>/studentAnalysis/ajaxLessonImg.htm", //会在下面进行代码演示 {img1:barBase64Info1,img2:barBase64Info2,img3:barBase64Info3,img4:barBase64Info4,img5:barBase64Info5},function(result){
if(result==""){
layer.msg("网络链接超时!")
}else{
alert(result);
return;
var gradeName=$("#gradeName").val();
var className=$("#className").val();
var subjectName=$("#subjectName").val();
var lessonId=$("#lessonId").val();
var begintime=$("#begintime").val();
window.location.href="<%=path%>/studentAnalysis/importLessonWord.htm? //会在下面进行代码演示imgUrl="+result+"&gradeName="+gradeName+"&className="+className+"&subjectName="+subjectName+"&lessonId="+lessonId+"&begintime="+begintime;
}
});
//意思是先用post方法提交base64至后台,然后后台把base64转为图片存在指定服务器上,然后将图片名再返回到前台,用post请求的返回处理,再进行get请求,此时get请求带的参数就是图片简短的名称,不会出现参数过长的情况。是不是很明智。
接下来我们来看下
后台的处理代码:
@RequestMapping("ajaxLessonImg.htm")
@ResponseBody
public String ajaxLessonImg(HttpServletRequest request,HttpServletResponse response
) throws Exception{
Map<String,Object>map=new LinkedHashMap<>();
//图片临时存放目录
String file=System.getProperty("catalina.home")+\\webapps\\PicServer\\tempImg\\; //图片要存放的路径
String img1=request.getParameter("img1").toString();
String img2=request.getParameter("img2").toString();
String img3=request.getParameter("img3").toString();
String img4=request.getParameter("img4").toString();
String img5=request.getParameter("img5").toString();
String[] imgArray={img1,img2,img3,img4,img5};
List<String>fileList=new ArrayList<>();
for(String base64:imgArray){
String fileName=ImageUtil.savePictoServer(base64,file); //将base64转为图片的方法
fileList.add(fileName);
}
return new Gson().toJson(fileList);
}
上面gson用到的包
展示imgutil里如果对base64进行处理解码还原:
/**
* 将一个base64转换成图片保存在 path文件夹下 ,命名随机
* @param base64String
* @param path 是一个文件夹路径
* @param imgName 图片名字(没有后缀)
* @throws Exception
*/
public static String savePictoServer(String base64String,String path)throws Exception{
BASE64Decoder decoder = new BASE64Decoder(); //此类需引入的jar包
//要把+在上传时变成的空格再改为+
base64String = base64String.replaceAll(" ", "+");
//去掉“data:image/png;base64,”后面才是base64编码,去掉之后才能解析
base64String = base64String.replace("data:image/png;base64,","");
//在本地指定位置建立文件夹,path由控制台那边进行定义
File dir=new File(path);
if(!dir.exists()){
dir.mkdirs();
}
String uuidImg=UUID.randomUUID().toString()+".png";
String fileName=path+uuidImg;
try {
byte[] buffer = decoder.decodeBuffer(base64String);
OutputStream os = new FileOutputStream(fileName);
for(int i =0;i<buffer.length;++i){
if(buffer[i]<0){//调整异常数据
buffer[i]+=256;
}
}
os.write(buffer);
os.close();
} catch (IOException e) {
throw new RuntimeException();
}
return uuidImg;
}
需要用的base64相关的包:
接下来看看最终使用freemarker模板,并弹出下载弹出框的代码:
@RequestMapping("importLessonWord.htm")
public void importLessonWord(HttpServletRequest request,HttpServletResponse response,@ModelAttribute("gradeName")String gradeName,@ModelAttribute("className")String className,
@ModelAttribute("subjectName")String subjectName,@ModelAttribute("lessonId")String lessonId,@ModelAttribute("begintime")String begintime
) throws Exception{
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd");
String time=sdf.format(new Date());
Map<String,Object>map=new LinkedHashMap<>();
String file=System.getProperty("catalina.home")+tempDirectory;
String imgUrl=request.getParameter("imgUrl").toString();
final List<String>fileList=new Gson().fromJson(imgUrl, List.class);
//图片64位数编码(img1,img2,img3,img4,img5)
int i=1;
for(String fileName:fileList){
String imgBase64=ImageUtil.getImageStr(file+fileName); //模板需要传入base64所以又要将图片转为base64,代码如下代码块
map.put("img"+i,imgBase64);
i++;
}
//开启一个线程删除临时存放的统计图图片
new Thread(){
public void run() {
for(String fileName:fileList){
String fileUrl=System.getProperty("catalina.home")+tempDirectory;
File file = new File(fileUrl+fileName);
if(file.exists()){
file.delete();
}
}
}
}.start();
Template dateTmp = getTemplateObject("lesson.ftl",request);
//文件名称
String creadeFile = java.net.URLEncoder.encode("课堂分析报表-" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()), "UTF-8");
//获取输出字符对象
PrintWriter pw=response.getWriter();
// 生成提示信息
response.setContentType("application/vnd.ms-doc");
// 设置响应头
response.setHeader("content-disposition", "attachment;filename="+creadeFile+".doc");
dateTmp.process(map, pw);
}
/**
* 读取图片在本地存储的位置
* @param imgFile
* @throws Exception
*/
public static String getImageStr(String imgFile) {
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}