java 动态导出word

1.zip压缩文件2.xml文件,需要替换的用特定的字符替换。

package com.bootdo.common.utils;

import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.util.ResourceUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;


/**
 * FileUtil
 *
 * @author system
 * @date 2018.09.26
 */
public class WordUtils {

	//配置信息
	private static
	Configuration configuration = null;
	static {
		configuration = new Configuration();
		configuration.setDefaultEncoding("utf-8");
	}

	private WordUtils() {
		throw new AssertionError();
	}


	/**
	 * 获取模板字符串输入流
	 * @param dataMap   参数
	 * @param templateName  模板名称
	 * @return
	 */
	public static ByteArrayInputStream getFreemarkerContentInputStream(Map dataMap, String templateName) {
		ByteArrayInputStream in = null;
		try {
			ApplicationHome appHome = new ApplicationHome();
			File docxFile = new File(appHome.getDir().getPath() + File.separator + "/templateFiles");
//			String filePath = ResourceUtils.getURL("classpath:static/resources").getPath();
			configuration.setDirectoryForTemplateLoading(docxFile);
			//获取模板
			Template template = configuration.getTemplate(templateName);
			StringWriter swriter = new StringWriter();
			//生成文件
			template.process(dataMap, swriter);

			// 这里一定要设置utf-8编码 否则导出的word中中文会是乱码
			in = new ByteArrayInputStream(swriter.toString().getBytes("utf-8"));
		} catch (Exception e) {
		}
		return in;
	}

	/**
	 * 导出.docx文件
	 * @param dataMap 导出动态参数
	 * @param templateName xml模板名称
	 * @param filePath 导出文件路径
	 * @param templateWord zip模板
	 */
	public static void createDocx(Map dataMap, String templateName, String filePath, String templateWord) {
		ZipOutputStream zipout = null;
		OutputStream outputStream = null;
		try {
//			inputStream2File();
			// 导出文件
			File outFile = new File(filePath);
			outputStream = new FileOutputStream(outFile);

			//内容模板
			ByteArrayInputStream documentInput = getFreemarkerContentInputStream(dataMap, templateName);
			// 换成自己的zip路径
			ApplicationHome appHome = new ApplicationHome();
			File docxFile = new File(appHome.getDir().getPath() + File.separator + "/templateFiles" + "/"+templateWord);
			if (!docxFile.exists()) {
				docxFile.createNewFile();
			}
			ZipFile zipFile = new ZipFile(docxFile);
			Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
			zipout = new ZipOutputStream(outputStream);
			//开始覆盖文档------------------
			int len = -1;
			byte[] buffer = new byte[1024];
			while (zipEntrys.hasMoreElements()) {
				ZipEntry next = zipEntrys.nextElement();
				InputStream is = zipFile.getInputStream(next);
				if (next.toString().indexOf("media") < 0) {
					zipout.putNextEntry(new ZipEntry(next.getName()));
					// 如果是word/document.xml由我们输入
					if ("word/document.xml".equals(next.getName())) {
						if (documentInput != null) {
							while ((len = documentInput.read(buffer)) != -1) {
								zipout.write(buffer, 0, len);
							}
							documentInput.close();
						}
					} else {
						while ((len = is.read(buffer)) != -1) {
							zipout.write(buffer, 0, len);
						}
						is.close();
					}
				}
			}

		} catch (Exception e) {
			System.out.println("word导出失败:"+e.getStackTrace());
			e.printStackTrace();
		}finally {
			if(zipout!=null){
				try {
					zipout.close();
				} catch (IOException e) {
					System.out.println("io异常");

				}
			}
			if(outputStream!=null){
				try {
					outputStream.close();
				} catch (IOException e) {
					System.out.println("io异常");
				}
			}
		}
	}


	/**
	 * 导出.docx文件并通过浏览器下载(带图片)
	 * @param dataMap 数据map
	 * @param documentXmlRels rels模板
	 * @param document xml模板
	 * @param template zip模板
	 * @param outputStream
	 */
	public static void createDocxImg(Map dataMap, String documentXmlRels, String document, String template, OutputStream outputStream) {
		ZipOutputStream zipout = null;
		try {
			// 图片配置文件模板
			ByteArrayInputStream documentXmlRelsInput = getFreemarkerContentInputStream(dataMap, documentXmlRels);
			// 内容模板
			ByteArrayInputStream documentInput =  getFreemarkerContentInputStream(dataMap, document);
			// 最初设计的模板
			ApplicationHome appHome = new ApplicationHome();
			File docxFile = new File(appHome.getDir().getPath() + File.separator + "/templateFiles" + "/" + template);
			if (!docxFile.exists()) {
				docxFile.createNewFile();
			}
			ZipFile zipFile = new ZipFile(docxFile);
			Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
			zipout = new ZipOutputStream(outputStream);
			//开始覆盖文档------------------
			int len = -1;
			byte[] buffer = new byte[1024];
			while (zipEntrys.hasMoreElements()) {
				ZipEntry next = zipEntrys.nextElement();
				InputStream is = zipFile.getInputStream(next);
				if (next.toString().indexOf("media") < 0) {
					zipout.putNextEntry(new ZipEntry(next.getName()));
					// 如果是document.xml.rels由我们输入
					if (next.getName().indexOf("document.xml.rels") > 0) {
						if (documentXmlRelsInput != null) {
							while ((len = documentXmlRelsInput.read(buffer)) != -1) {
								zipout.write(buffer, 0, len);
							}
							documentXmlRelsInput.close();
						}
					} else if ("word/document.xml".equals(next.getName())) {//如果是word/document.xml由我们输入
						if (documentInput != null) {
							while ((len = documentInput.read(buffer)) != -1) {
								zipout.write(buffer, 0, len);
							}
							documentInput.close();
						}
					} else {
						while ((len = is.read(buffer)) != -1) {
							zipout.write(buffer, 0, len);
						}
						is.close();
					}
				}
			}
			//写入图片
			List<Map<String, Object>> picList = (List<Map<String, Object>>) dataMap.get("picList");
			for (Map<String, Object> pic : picList) {
				ZipEntry next = new ZipEntry("word" + File.separator + "media" + File.separator + pic.get("fileName"));
				zipout.putNextEntry(new ZipEntry(next.toString()));
				InputStream in = new FileInputStream((File)pic.get("file"));
				while ((len = in.read(buffer)) != -1) {
					zipout.write(buffer, 0, len);
				}
				in.close();
			}
//			download(outFile, response, fileName);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(zipout!=null){
				try {
					zipout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outputStream!=null){
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 *下载生成的word文件并删除临时文件
	 */
	public static void download(File file , HttpServletResponse response, String fileName){

		ServletOutputStream out = null;
		FileInputStream inputStream = null;
		try {

			response.reset();//清除空白行纺织报错
			response.setHeader("Access-Control-Allow-Origin", "*");//所有域都可以跨
			response.setHeader("Content-Type", "application/octet-stream;charset=UTF-8");//二进制  流文件
			response.setHeader("Content-Disposition", "attachment; filename="+
					String.valueOf(URLEncoder.encode(fileName, "UTF-8")));
			response.setHeader("Connection", "close");//关闭请求头连接
			//设置文件在浏览器打开还是下载
			response.setContentType("application/x-download");

//			response.setCharacterEncoding("utf-8");
//			response.setContentType("application/x-download");
//			response.setHeader("Content-Disposition", "attachment; filename="+
//					String.valueOf(URLEncoder.encode(fileName, "UTF-8")));
			out = response.getOutputStream();
			inputStream = new FileInputStream(file);
			byte[] buffer = new byte[512];
			int bytesToRead = -1;
			// 通过循环将读入的Word文件的内容输出到浏览器中
			while((bytesToRead = inputStream.read(buffer)) != -1){
				out.write(buffer, 0, bytesToRead);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				if(null!=out) {
					out.close();
				}
				if(null!=inputStream) {
					inputStream.close();
				}
				file.delete();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}


	/**
	 * 将inputStream转化为file
	 * @param
	 * @param
	 */
	public static void inputStream2File() throws IOException {
		OutputStream os = null;
		InputStream is = null;
		String[] files = {"hgtsjgzyq_template.xml","hgtsjgzyq_template.zip","kszy_template.xml","kszy_template.zip","dlssthjjwjbpd_template.xml","dlssthjjwjbpd_template.zip","dlssthjjwjbpd_template.xml.rels"};
		try {
			ApplicationHome appHome = new ApplicationHome();
			File path = new File(appHome.getDir().getPath() + File.separator + "/templateFiles");
			if (path.exists()) {
				path.delete();
				path.mkdir();
			} else {
				path.mkdir();
			}
			for (int i = 0; i < files.length; i++) {
				File file = new File(appHome.getDir().getPath() + File.separator + "/templateFiles/" + files[i]);
				if (file.exists()) {
					file.delete();
					file.createNewFile();
				} else {
					file.createNewFile();
				}
				is = WordUtils.class.getClassLoader().getResourceAsStream("static/resources/" + files[i]);
				os = new FileOutputStream(file);
				int len = 0;
				byte[] buffer = new byte[8192];

				while ((len = is.read(buffer)) != -1) {
					os.write(buffer, 0, len);
				}
			}

		} finally {
			if (os != null) {
				os.close();
			}
			if (is != null) {
				is.close();
			}

		}
	}


}


调用

WordUtils.createDocx(map, "xxx.xml", bootdoConfig.getUploadPath() + "/" + fileUuid + ".docx", "xxx.zip");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值