1.引入jar包(aspose-words-15.8.0.jar)
2.配置jar包
<!--word操作工具类-->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.9.1</version>
</dependency>
3.导出版本配置
4.导出类代码(WordExportUtil)
public class WordExportUtil {
private static String TEMPLATE_PACKAGE = "wordTemplate/";
/**
* <p>
* 导出模板到输出流中
* <ul>
* <li> templateName —— 模板文件名称
* <ul>
* <li> 模板文件名称: book.docx
* <li> 入参: "book.docx"
* </ul>
* <li> dataMap —— 待填充数据
* dataMap一般与实体对应,其中key对应模板中占位符字符,如:
* <ul>
* <li> 实体类属性:String name = "张三";
* <li> 模板占位符:姓名:{{name}}
* </ul>
* <li> outStream —— 输出流,如:response.getOutputStream()
* </ul>
*</p>
* @param templateName 项目webapp/wordTemplate目录下模板文件名称
* @param dataMap 需要填充进模板的数据
* @param outStream 需要被写入的流
* @throws IOException
*/
public static void exportWord(@NotNull String templateName, @NotNull Map dataMap, @NotNull OutputStream outStream) throws IOException {
try{
//配置
String path = IOUtil.webappDirPath(templateName);
path = path + TEMPLATE_PACKAGE + templateName;
XWPFTemplate template = XWPFTemplate.compile(new File(path)).render(dataMap);
template.writeAndClose(outStream);
}catch (IOException e){
throw new RuntimeException("生成文件失败!");
}
}
/**
* 导出word文件
* @param response 当前会话响应对象
* @param dataMap 包含数据的Map
* @param fileName 希望命名的下载文件名
* @throws IOException
*/
public static void exportViaResponse(@NotNull HttpServletResponse response,
@NotNull Map dataMap,
String templateName,
String fileName) throws IOException {
OutputStream outputStream = response.getOutputStream();
response.reset();
if(StringUtils.isBlank(fileName)){
fileName = DateUtil.formatDate(new Date(), "yyyyMMddHHmmss") + ".docx";
}
response.addHeader("Content-Disposition",
new String(("attachment;filename=" + fileName).getBytes(),
"ISO8859-1"));
response.setContentType("application/octet-stream");
exportWord(templateName,
dataMap,
outputStream);
outputStream.flush();
outputStream.close();
}
}
注: private static String TEMPLATE_PACKAGE = "wordTemplate/"; 是导出模板的位置,可以自行修改
5.数据输出流 类(IOUtil)
public class IOUtil {
/**
* 将输入流转换为字节数据输出流,可以多次使用相同内容的输入流
* @param inputStream 输入流
* @return
* @throws IOException
*/
public static synchronized ByteArrayOutputStream getByteArrayOutPutStream(InputStream inputStream) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len=-1;
while ((len = inputStream.read(buffer)) != -1 ) {
baos.write(buffer, 0, len);
}
baos.flush();
return baos;
}
/**
* 获取资源文件的文件流
*
* @return
*/
public static InputStream getResourceInputStream(String filePath) {
InputStream in = Object.class.getResourceAsStream(filePath);
if (in != null) {
return in;
}
return null;
}
/**
* 获取运行时类根目录路径
* @return 运行时类根目录路径
*/
public static String classesDirPath(Object object){
return new IOUtil().getClass().getResource("/").getPath();
}
/**
* 获取运行时webapp目录
* @return
*/
public static String webappDirPath(Object object){
return classesDirPath(object).replaceAll( "WEB-INF/classes/" , "" );
}
}
6.数据转换类(BeanMapTranslateUtil)
public class BeanMapTranslateUtil {
/**
* LOGGER
*/
private static final Logger LOGGER = LoggerFactory.getLogger(BeanMapTranslateUtil.class);
/**
* Map转换Obj
*
* @param map map对象
* @param obj obj对象
*/
public static void transMap2Bean(Map<String, Object> map, Object obj) {
if (map == null || obj == null) {
return;
}
try {
BeanUtils.populate(obj, map);
} catch (Exception e) {
LoggerUtil.error(LOGGER, "transMap2Bean执行错误", e);
}
}
/**
* Obj转换Map
*
* @param obj obj对象
* @return map对象
*/
public static Map<String, Object> transBean2Map(Object obj) {
if (obj == null) {
return null;
}
Map<String, Object> map = new HashMap<String, Object>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
// 过滤class属性
if (!"class".equals(key)) {
// 得到property对应的getter方法
Method getter = property.getReadMethod();
Object value = getter.invoke(obj);
map.put(key, value);
}
}
} catch (Exception e) {
LOGGER.error("transBean2Map执行错误", e);
}
return map;
}
/**
* Obj转换Map<String, String>
*
* @param obj obj对象
* @return map对象
*/
public static Map<String, String> transBean2StringMap(Object obj) {
if (obj == null) {
return null;
}
Map<String, String> map = new HashMap<String, String>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
// 过滤class属性
if (!"class".equals(key)) {
// 得到property对应的getter方法
Method getter = property.getReadMethod();
String value = String.valueOf(getter.invoke(obj));
map.put(key, value);
}
}
} catch (Exception e) {
LOGGER.error("transBean2Map执行错误", e);
}
return map;
}
}
7.错误异常类(LoggerUtil)
public class LoggerUtil {
public static final Logger LOGGER = LoggerFactory.getLogger(LoggerUtil.class);
/**
* 异常
*
* @param logger 日志对象
* @param ex 异常对象
* @param text 异常信息
* @param params 异常信息占位参数
*/
public static void exception(Logger logger, Exception ex, String text, Object... params) {
if (params == null || params.length == 0) {
logger.error(" - t:`" + text + "`");
return;
}
String[] keys = getKeys(params);
Object[] values = getValues(params);
String paraName = generateParaName(keys);
logger.error("t:`" + text + "` - p:{" + paraName + "}" + "- val:{" + toJson(values) + "}", ex);
}
/**
* 异常(带占位参数)
*
* @param logger 日志对象
* @param ex 异常对象
* @param text 异常信息
*/
public static void exception(Logger logger, Exception ex, String text) {
logger.error("t:`" + text + "`", ex);
}
/**
* 错误
*
* @param text 错误文本
* @param params 错误信息占位参数
*/
public static void error(Logger logger, String text, Object... params) {
if (params == null || params.length == 0) {
logger.error("t:`" + text + "`");
return;
}
String[] keys = getKeys(params);
Object[] values = getValues(params);
String paraName = generateParaName(keys);
logger.error("t:`" + text + "` - p:{" + paraName + "}", toJson(values));
}
/**
* 警告
*
* @param logger 日志对象
* @param tag 警告标记
* @param text 警告文本
* @param params 警告文本占位参数
*/
public static void warn(Logger logger, String tag, String text, Object... params) {
if (params == null || params.length == 0) {
logger.warn(tag + " - t:`" + text + "`");
return;
}
String[] keys = getKeys(params);
Object[] values = getValues(params);
String paraName = generateParaName(keys);
logger.warn(tag + " - t:`" + text + "` - p:{" + paraName + "}", toJson(values));
}
public static void info2in(Logger logger, String tag, Object... params) {
info(logger, tag, "IN", params);
}
public static void info2out(Logger logger, String tag, Object... params) {
info(logger, tag, "OUT", params);
}
public static void info(Logger logger, String tag, String text, Object... params) {
if (!logger.isInfoEnabled()) {
return;
}
if (params == null || params.length == 0) {
logger.info(tag + " - t:`" + text + "`");
return;
}
if (params.length % 2 != 0) {
try {
logger.info(tag + " - t:`" + text + "` - p:{" + toJson(params) + "}");
} catch (Exception ex) {
exception(logger,
ex,
tag,
"Parameter mismatch , Convert to JSON exception., params");
}
return;
}
String[] keys = getKeys(params);
Object[] values = getValues(params);
String paraName = generateParaName(keys);
logger.info(tag + " - t:`" + text + "` - p:{" + paraName + "}", values);
}
public static void debug(Logger logger, String tag, String text, Object... params) {
if (!logger.isDebugEnabled()) {
return;
}
if (params == null || params.length == 0) {
logger.debug(tag + " - t:`" + text + "`");
return;
}
String[] keys = getKeys(params);
Object[] values = getValues(params);
String paraName = generateParaName(keys);
logger.debug(tag + " - t:`" + text + "` - p:{" + paraName + "}", toJson(values));
}
public static <V> Map<String, V> getMap(Object[] objects) {
String[] keys = getKeys(objects);
V[] values = getValues(objects);
int minl = keys.length;
if (keys.length != values.length) {
LOGGER.error("getMap(...) exception,keys.length != values.length");
/*
* key 和val 的 length 不相等时,取 leng最小值作为循环的max.
*/
minl = keys.length <= values.length ? keys.length : values.length;
}
Map<String, V> map = new HashMap<>();
for (int i = 0; i < minl; i++) {
map.put(keys[i], values[i]);
}
return map;
}
@SuppressWarnings("unchecked")
private static <V> V[] getValues(Object[] objects) {
if (objects.length <= 1) {
return (V[]) objects;
}
Object[] values = new Object[objects.length / 2];
int j = 0;
for (int i = 0; i < objects.length; i++) {
if ((i + 1) % 2 == 0) {
values[j] = objects[i];
j++;
}
}
return (V[]) values;
}
private static String[] getKeys(Object[] objects) {
if (objects.length <= 1) {
String key = objects.length == 1 ? objects[0].toString() : "key";
return new String[]{key};
}
String[] keys = new String[objects.length % 2 == 0 ? objects.length / 2 : objects.length / 2 + 1];
int j = 0;
int num = objects.length / 2;
for (int i = 0; i < objects.length; i++) {
if (objects.length % 2 != 0 && j >= num) {
keys[j] = "";
continue;
}
if ((i + 1) % 2 != 0) {
keys[j] = objects[i].toString();
j++;
}
}
return keys;
}
private static String generateParaName(String[] keys) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < keys.length; i++) {
sb.append(keys[i] + "={}");
if (i != keys.length - 1) {
sb.append(",");
}
}
return sb.toString();
}
private static Object[] toJson(Object... obj) {
Object[] strs = new Object[obj.length];
for (int i = 0; i < obj.length; i++) {
if (obj[i] == null) {
strs[i] = "null";
} else if (obj[i] instanceof String || NumberUtils.isDigits(obj[i].toString())) {
strs[i] = obj[i];
} else {
strs[i] = JSON.toJSONString(obj[i]);
}
}
return strs;
}
/*
public static class SimpleLogUtil {
private final static String fileName = LoggerUtil.class.getSimpleName() + ".java";
private final static String prefix = "com.yaowan";
private static String tag(StackTraceElement ste) {
String[] arrays = ste.getFileName().split("\\.");
String tag;
if (arrays != null && arrays.length > 0) {
return arrays[0] + "." + ste.getMethodName() + ":" + ste.getLineNumber();
} else {
tag = "uk";
}
return tag;
}
private static String tag() {
StackTraceElement[] stes = Thread.currentThread().getStackTrace();
if (!stes[3].getFileName().equals(fileName) && stes[3].getClassName().contains(prefix)) {
return tag(stes[3]);
}
for (StackTraceElement ste : stes) {
if (ste.getFileName().equals(fileName)) {
continue;
}
if (ste.getClassName().contains(prefix)) {
return tag(ste);
}
}
return "tag:nil";
}
public static void exception(Logger logger, Exception ex) {
LoggerUtil.exception(logger, ex, "");
}
public static void exception(Logger logger, Exception ex, String text) {
LoggerUtil.exception(logger, ex, text);
}
public static void exception(Logger logger, Exception ex, String text, Object... params) {
LoggerUtil.exception(logger, ex, text, params);
}
public static void warn(Logger logger, String text, Object... params) {
LoggerUtil.warn(logger, tag(), text, params);
}
public static void warn(Logger logger, Class<?> class1, String text, Object... params) {
LoggerUtil.warn(logger, "tag:" + class1.getSimpleName(), text, params);
}
public static void error(Logger logger, String text, Object... params) {
LoggerUtil.error(logger, text, params);
}
public static void info(Logger logger, String text, Object... params) {
LoggerUtil.info(logger, tag(), text, params);
}
public static void info(Logger logger, Class<?> class1, String text, Object... params) {
LoggerUtil.info(logger, "tag:" + class1.getSimpleName(), text, params);
}
public static void debug(Logger logger, String text, Object... params) {
if (!LOGGER.isDebugEnabled()) {
return;
}
LoggerUtil.debug(logger, tag(), text, params);
}
public static void debug(Logger logger, Class<?> class1, String text, Object... params) {
LoggerUtil.debug(logger, "tag:" + class1.getSimpleName(), text, params);
}
}
public static String toBase64(String msg) {
String result = "";
if (StringUtils.isNotBlank(msg)) {
result = toBase64(msg.getBytes());
}
return result;
}*/
public static String toBase64(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return "nil";
}
if (bytes.length > 1024) {
return "too big";
}
String str = "";
try {
str = Base64.encode(bytes);
} catch (Exception ex) {
LOGGER.info("toBase64异常[bytes.length={}]", bytes.length);
}
return str;
}
}
8.实现代码
@RequestMapping(value = "{id}/exportApplication", method = RequestMethod.GET)
public void exportApplication(@PathVariable("id") String id, HttpServletResponse response, HttpServletRequest request)
throws Exception {
BusProDecision meeting = get(id);//查询数据
Map<String, Object> map = BeanMapTranslateUtil.transBean2Map(meeting);
WordExportUtil.exportViaResponse(response, map, "project.docx",
meeting.getProName()+ "表.docx");
}
9.word 模板
注:循环查询多条数据查询导出 后面持续更新