word导出 以及批量导出并压缩
程序员文章站
2022-07-04 17:02:56
...
package com.hesc.wpc.common.utils; import java.io.ByteArrayOutputStream; 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.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.Date; import java.util.List; import java.util.Map; import javax.mail.internet.MimeUtility; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import com.hesc.wpc.web.controller.admin.meeting.view.MeetingView; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; import freemarker.template.Template; import sun.misc.BASE64Encoder; /** * 生成word文档工具类 * @author ypf * @date 2017-05-17 */ public class WordUtil { private static final Logger logger = LoggerFactory.getLogger(MeetingView.class); private static Configuration configuration = null; static { configuration = new Configuration(); configuration.setDefaultEncoding("utf-8"); try { ResourceLoader resourceLoader = new DefaultResourceLoader(); //指定模板目录在类路径:WEB-INF/classes Resource resource = resourceLoader.getResource("/"); File file = resource.getFile(); //设置要解析的模板所在的目录,并加载模板文件 configuration.setDirectoryForTemplateLoading(file); ///设置包装器,并将对象包装为数据模型 configuration.setObjectWrapper(new DefaultObjectWrapper()); } catch (IOException e) { e.printStackTrace(); } } /** * 根据类路径获取模板 * @param templatePath * @param templateName * @return * @throws IOException */ private static Template getTemplate(String templatePath, String templateName) throws IOException { Configuration configuration = new Configuration(Configuration.VERSION_2_3_23); configuration.setDefaultEncoding("UTF-8"); configuration.setDirectoryForTemplateLoading(new File(templatePath)); return configuration.getTemplate(templateName, "UTF-8"); } /** * 导出word 文档 * @param typeName 会议类型名称 * @param dataMap 数据 * @param xmlpath xml 模板路径 * @param response * @param request */ public static void createWord(String typeName,Map<String, Object> dataMap,String xmlpath,HttpServletResponse response, HttpServletRequest request){ Template t = null; try { t = getTemplate(request.getSession().getServletContext().getRealPath("/"), xmlpath); } catch (IOException e1) { e1.printStackTrace(); } File file = null; InputStream fin = null; ServletOutputStream out =null; file = createDocx(dataMap,t,request); try { fin = new FileInputStream(file); String filename=encodeFilename(typeName+".doc", request); response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=\""+filename+"\""); out = response.getOutputStream(); byte [] buffer=new byte[512]; int byteToRead = -1; while((byteToRead = fin.read(buffer)) != -1){ out.write(buffer, 0, byteToRead); } } catch (IOException e) { logger.error("word文档导出错误:"+e.getMessage()); }finally{ try { if(null != fin){ fin.close(); } if(null != out){ out.flush(); out.close(); } } catch (IOException e) { logger.error("word文档导出错误:"+e.getMessage()); } } } /** * 导出word 文档 * @param typeName 会议类型名称 * @param dataMap 数据 * @param xmlpath xml 模板路径 * @param response * @param request */ public static void createWord(String typeName,List<Map<String, Object>> mapList,String xmlpath,HttpServletResponse response, HttpServletRequest request){ Template t = null; try { t = getTemplate(request.getSession().getServletContext().getRealPath("/"), xmlpath); } catch (IOException e1) { e1.printStackTrace(); } File file = null; InputStream fin = null; ServletOutputStream out =null; for(int i=0;i<mapList.size();i++) { Map<String, Object> map=mapList.get(i); file = createDocx(map,t,request); } try { fin = new FileInputStream(file); String filename=encodeFilename(typeName+".doc", request); response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=\""+filename+"\""); out = response.getOutputStream(); byte [] buffer=new byte[512]; int byteToRead = -1; while((byteToRead = fin.read(buffer)) != -1){ out.write(buffer, 0, byteToRead); } } catch (IOException e) { logger.error("word文档导出错误:"+e.getMessage()); }finally{ try { if(null != fin){ fin.close(); } if(null != out){ out.flush(); out.close(); } } catch (IOException e) { logger.error("word文档导出错误:"+e.getMessage()); } } } /** * 生成word文档 * @param dataMap * @param t * @param request * @return */ public static File createDocx(Map<String, Object> dataMap,Template t, HttpServletRequest request){ String path = request.getSession().getServletContext().getRealPath("/temlate.docx"); File f=new File(path); Writer out = null; try { out = new OutputStreamWriter(new FileOutputStream(f),"utf-8"); t.process(dataMap, out); } catch (Exception e) { e.printStackTrace(); }finally{ try { if(null !=out){ out.flush(); out.close(); } } catch (IOException e) { logger.error("创建word文档错误:"+e.getMessage()); } } return f; } /** * 将图片转换为base64存储 */ public static String getImageStr(String imgfilepath) { if (imgfilepath == null || "".equals(imgfilepath.trim())){ return ""; } try { URL u = new URL(imgfilepath); HttpURLConnection conn = (HttpURLConnection) u.openConnection(); conn.setRequestMethod("GET"); // 设置超时响应时间为10秒 conn.setConnectTimeout(10000); // 通过输入流获取图片数据 InputStream inStream = conn.getInputStream(); // 读取图片字节数组 byte[] data = readInputStream(inStream); BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data); } catch (Exception e) { logger.error("图片转换为base64存储错误:"+e.getMessage()); } return ""; } public static byte[] readInputStream(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); //创建一个Buffer字符串 byte[] buffer = new byte[1024]; //每次读取的字符串长度,如果为-1,代表全部读取完毕 int len = 0; //使用一个输入流从buffer里把数据读取出来 while( (len=inStream.read(buffer)) != -1 ){ //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度 outStream.write(buffer, 0, len); } //关闭输入流 inStream.close(); //把outStream里的数据写入内存 return outStream.toByteArray(); } /** * 对文件名进行编码 * @param filename * @param request * @return */ private static String encodeFilename(String filename, HttpServletRequest request) { String agent = request.getHeader("USER-AGENT"); try { if (agent != null) { if (-1 != agent.indexOf("MSIE") || -1 != agent.indexOf("Trident") || -1 != agent.indexOf("Chrome")) { // ie,chrome String newFileName = URLEncoder.encode(filename, "UTF-8"); newFileName = StringUtils.replace(newFileName, "+", "%20"); if (newFileName.length() > 150) { newFileName = new String(filename.getBytes("GB2312"), "ISO8859-1"); newFileName = StringUtils.replace(newFileName, " ", "%20"); } return newFileName; } else if (-1 != agent.indexOf("Mozilla")) { // firefox return MimeUtility.encodeText(filename, "UTF-8", "B"); } } return filename; } catch (Exception ex) { logger.error(ex.getMessage(), ex); return filename; } } /* *压缩包方式导出多个word *由于一次请求浏览器只能响应一次,想导出多个必须打包,亲测for循环导出只能导一个 *如果想做到分别单独下载,那就得用插件啦,这里不提供插件的做法 *思路:生成临时目录-在临时目录生成word-将临时目录打zip包-zip文件下载-删除临时目录和zip包, * 回收系统资源 */ public static void exportWordBatch(String typeName,List<Map<String, Object>> mapList,String ftlFile ,HttpServletRequest request,HttpServletResponse response) { File file = null; File zipfile=null; File directory=null; InputStream fin = null; ServletOutputStream out = null; String filename=encodeFilename(typeName, request); response.setCharacterEncoding("utf-8"); response.setContentType("application/octet-stream"); response .addHeader("Content-Disposition", "attachment;filename="+ filename+".zip"); try { Template freemarkerTemplate = null; try { freemarkerTemplate = getTemplate(request.getSession().getServletContext().getRealPath("/"), ftlFile); } catch (IOException e1) { e1.printStackTrace(); } out = response.getOutputStream(); //根据当前时间和用户id创建临时目录 String time =DateUtil.format(System.currentTimeMillis(), "yyyy-MM-dd"); String path=request.getRealPath("/resources/word/"+time+""); directory=new File(path); directory.mkdirs(); for(int i=0;i<mapList.size();i++) { Map<String, Object> map=mapList.get(i); //List<Map<String, Object>> list = (List<Map<String, Object>>) map.get("datalist"); String title=map.get("title").toString()+"_"+i; // 调用工具类的createDoc方法在临时目录下生成Word文档 file = createDoc(map,freemarkerTemplate,directory.getPath()+"/"+title+".doc"); } //压缩目录 ZipUtils.createZip(path, path+".zip"); //根据路径获取刚生成的zip包文件 zipfile=new File(path+".zip"); fin=new FileInputStream(zipfile); byte[] buffer = new byte[512]; // 缓冲区 int bytesToRead = -1; // 通过循环将读入的Word文件的内容输出到浏览器中 while ((bytesToRead = fin.read(buffer)) != -1) { out.write(buffer, 0, bytesToRead); } }catch (Exception e) { e.printStackTrace(); } finally { try { if (fin!=null) fin.close(); if (out!=null) out.close(); if (zipfile!=null) zipfile.delete(); if (directory!=null) { //递归删除目录及目录下文件 ZipUtils.deleteFile(directory); } } catch (Exception e2) { e2.printStackTrace(); } } } //生成word文档方法 private static File createDoc(Map<?, ?> dataMap, Template template,String filename) { File f = new File(filename); //Template t = template; Writer w =null; FileOutputStream fos=null; try { // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开 fos=new FileOutputStream(f); w = new OutputStreamWriter(fos, "utf-8"); //不要偷懒写成下面酱紫: 否则无法关闭fos流,打zip包时存取被拒抛异常 //w = new OutputStreamWriter(new FileOutputStream(f), "utf-8"); template.process(dataMap, w); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } finally { try { fos.close(); w.close(); } catch (Exception e) { e.printStackTrace(); } } return f; } }
package com.hesc.wpc.common.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ZipUtils { private static final Logger log = LoggerFactory.getLogger(ZipUtils.class); private ZipUtils(){ } public static void doCompress(String srcFile, String zipFile) throws IOException { doCompress(new File(srcFile), new File(zipFile)); } /** * 文件压缩 * @param srcFile 目录或者单个文件 * @param zipFile 压缩后的ZIP文件 */ public static void doCompress(File srcFile, File zipFile) throws IOException { ZipOutputStream out = null; try { out = new ZipOutputStream(new FileOutputStream(zipFile)); doCompress(srcFile, out); } catch (Exception e) { throw e; } finally { out.close();//记得关闭资源 } } public static void doCompress(String filelName, ZipOutputStream out) throws IOException{ doCompress(new File(filelName), out); } public static void doCompress(File file, ZipOutputStream out) throws IOException{ doCompress(file, out, ""); } public static void doCompress(File inFile, ZipOutputStream out, String dir) throws IOException { if ( inFile.isDirectory() ) { File[] files = inFile.listFiles(); if (files!=null && files.length>0) { for (File file : files) { String name = inFile.getName(); if (!"".equals(dir)) { name = dir + "/" + name; } ZipUtils.doCompress(file, out, name); } } } else { ZipUtils.doZip(inFile, out, dir); } } public static void doZip(File inFile, ZipOutputStream out, String dir) throws IOException { String entryName = null; if (!"".equals(dir)) { entryName = dir + "/" + inFile.getName(); } else { entryName = inFile.getName(); } ZipEntry entry = new ZipEntry(entryName); out.putNextEntry(entry); int len = 0 ; byte[] buffer = new byte[1024]; FileInputStream fis = new FileInputStream(inFile); while ((len = fis.read(buffer)) > 0) { out.write(buffer, 0, len); out.flush(); } out.closeEntry(); fis.close(); } /** * 创建ZIP文件 * @param sourcePath 文件或文件夹路径 * @param zipPath 生成的zip文件存在路径(包括文件名) */ public static void createZip(String sourcePath, String zipPath) { FileOutputStream fos = null; ZipOutputStream zos = null; try { fos = new FileOutputStream(zipPath); zos = new ZipOutputStream(fos); writeZip(new File(sourcePath), "", zos); } catch (FileNotFoundException e) { log.error("ZipUtils createZip Failed to create ZIP file", e); } finally { try { if (zos != null) { log.debug("ZipUtils createZip Create a ZIP file successfully! the path in:{}",zipPath); zos.close(); //压缩成功后,删除打包前的文件 deleteFile( new File(sourcePath) ); } } catch (IOException e) { log.error("ZipUtils createZip Failed to create ZIP file", e); } } } private static void writeZip(File file, String parentPath, ZipOutputStream zos) { if (file.exists()) { if (file.isDirectory()) {// 处理文件夹 parentPath += file.getName() + File.separator; File[] files = file.listFiles(); for (File f : files) { writeZip(f, parentPath, zos); } } else { FileInputStream fis = null; try { fis = new FileInputStream(file); ZipEntry ze = new ZipEntry(parentPath + file.getName()); zos.putNextEntry(ze); byte[] content = new byte[1024]; int len; while ((len = fis.read(content)) != -1) { zos.write(content, 0, len); zos.flush(); } } catch (FileNotFoundException e) { log.error("ZipUtils createZip Failed to create ZIP file",e); } catch (IOException e) { log.error("ZipUtils createZip Failed to create ZIP file",e); } finally { try { if (fis != null) { fis.close(); } } catch (IOException e) { log.error("ZipUtils createZip Failed to create ZIP file",e); } } } } } /** * 删除文件夹 * @param file */ public static void deleteFile(File file) { if (file.exists()) { // 判断文件是否存在 if (file.isFile()) { // 判断是否是文件 file.delete(); } else if (file.isDirectory()) { // 否则如果它是一个目录 File files[] = file.listFiles(); // 声明目录下所有的文件 files[]; for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件 deleteFile(files[i]); // 把每个文件 用这个方法进行迭代 } } file.delete(); } } /* public static void main(String[] args) throws IOException { doCompress("D:/java/", "D:/java.zip"); }*/ }
下一篇: Android实现系统消息推送