Java动态生成模板
程序员文章站
2022-04-29 21:45:36
...
逻辑
(1)制作模板(手动)
微软docx文件----转zip文件(手动改后缀名)---解压—找到对应的xml文件,删除变量间多余的字符---压缩文件---转为docx(手动改后缀名)
(2)系统识别模板(替换模板中的变量为具体值)
找到模板文件----转zip文件(系统实现)---解压—找到对应的xml文件,替换文件中变量的值---压缩文件---转为docx(系统实现)
一、制作模板https://blog.csdn.net/super_DuoLa/article/details/109338707
二、代码核心
1、将对象转成map格式,方便赋值
package test.util;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils;
import org.restlet.engine.util.DateUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* 对象转换工具类
* @author Administrator
*
*/
public class BeanUtils {
private static List<String> namelist = new ArrayList<String>();
public static void objtomap(Object obj,Map<String,Object> dataMap,int level){
int plevel=level+1;
//利用反射机制获取类中的属性:表示获取引用所指的对象的所有属性值
PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(obj); //获取EnterPriseInformation对象中的所有属性
//将对象中的每一个属性以数组形式获取到
/*PropertyDescriptor类:(属性描述器)表示JavaBean类通过存储器导出一个属性。
1. getPropertyType(),获得属性的Class对象;
2. getReadMethod(),获得用于读取属性值的方法;
*/
for (int i = 0; i < origDescriptors.length; i++){
Method getMethod=origDescriptors[i].getReadMethod(); //获取属性方法getParking()
String name = origDescriptors[i].getName(); //属性名字parking
/*@JsonIgnore注解作用:此注解是类注解,作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。
此注解用于属性或者方法上(最好是属性上)
例:A.isAnnotationPresent(B.class);
大白话:B类型的注解是否在A类上。*/
if(getMethod.isAnnotationPresent(JsonIgnore.class))
continue;
if (PropertyUtils.isReadable(obj,name) &&PropertyUtils.isWriteable(obj, name)) {//可读写
try {
Object value = PropertyUtils.getSimpleProperty(obj, name); //根据对象和对象中的属性名获取属性值
if(namelist.size()<=level){
namelist.add(name);
}else{
namelist.set(level,name);
}
String sname="";
for(int j=0;j<level+1;j++){
if(j==0){
sname=namelist.get(j);
}else{
sname+="_"+namelist.get(j);
}
}
if(getMethod.isAnnotationPresent(WordField.class)){
WordField wordField=getMethod.getAnnotation(WordField.class);
String str=wordField.title();
int n=wordField.num();
List<String> list=new ArrayList<String>();
for(int x=0;x<n;x++){
list.add("");
}
if(value!=null){
String [] are=value.toString().split(",");
for(int m=0;m<are.length;m++){
list.set(Integer.parseInt(are[m]),"√");
}
}
dataMap.put(sname,list);
}else if(value==null){
dataMap.put(sname," ");
}else if("java.util.Date".equals(value.getClass().getName())){
Date date=(Date)value;
dataMap.put(sname,DateUtils.format(date,"yyyy-M-d").split("-"));
}else if("java.util.ArrayList".equals(value.getClass().getName())){
List<Object> list=(List<Object>)value;
for(int z=0;z<list.size();z++){
String tname=name+z;
if(namelist.size()<=level){
namelist.add(tname);
}else{
namelist.set(level,tname);
}
objtomap(list.get(z),dataMap,plevel);
}
}else if(value.getClass().getName().indexOf("java")!=-1){
dataMap.put(sname,value);
}else{
objtomap(value,dataMap,plevel);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
}
}
2、赋值到模板
//执行模板
public String process(String rootPath,String fileName, Map<String, Object> dataMap) {
String tempPath="L:/"+fileName+".docx"; //模板位置及名称
String handlePath=rootPath+"/model/"+fileName+".zip"; //压缩文件位置及名称
String orclPath=rootPath+"/model/"+fileName+".docx";
String workPath=rootPath+"/model/work"; //压缩的根目录
String clearPath=rootPath+"/model/";
FileUtils.deleteDirectory(clearPath); //删除:执行操作之前先删除原有文件,避免缓存导致文件不是最新内容
FileUtils.createDirectory(workPath); //新建
String docxPath=workPath+"/"+fileName+".docx"; //此路径用于在指定文件夹中创建docx文件
String zipPath=workPath+"/"+fileName+".zip";//此路径用于在指定文件夹中创建zip文件
FileUtils.copyFileCover(tempPath,docxPath,true);// 待复制的文件名 目标文件名 如果目标文件已存在,是否覆盖
File file = new File(docxPath); // 创建指向 当前程序执行的目录/文件 的对象
file.renameTo(new File(zipPath));//修改文件名or格式 docx--->zip
FileUtils.unZipFiles(zipPath,workPath); //解压zipPath文件到workPath
FileUtils.deleteFile(zipPath); //删除压缩文件
FreeMarkers.process(workPath+"/word/document.xml",dataMap); //赋值:路径--值
FileUtils.zipFiles(workPath,"",handlePath); // 压缩的根目录 根目录下的待压缩的文件名或文件夹名,其中*或""表示跟目录下的全部文件 目标zip文件
File file1 = new File(handlePath); // 创建一个指向 当前程序执行的目录/文件 的对象
file1.renameTo(new File(orclPath)); //修改文件名or格式 zip--->docx
return orclPath; //返回操作完毕的文件
}
3、下载文件
//下载模板
public void download(String oraPath, HttpServletRequest request, HttpServletResponse response) {
File orclfile=new File(oraPath);
String fileName=orclfile.getName();
try {
response.reset();
response.setContentType("application/octet-stream; charset=utf-8");
final String userAgent = request.getHeader("USER-AGENT");
String finalFileName = null;
if(StringUtils.contains(userAgent, "Mozilla")){//google,火狐浏览器
finalFileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
}else{
finalFileName=Encodes.urlEncode(fileName);
}
response.setHeader("Content-Disposition", "attachment; filename="+finalFileName);
InputStream in = new FileInputStream(oraPath);
OutputStream out;
out = response.getOutputStream();
//写文件
int b;
while((b=in.read())!= -1)
{
out.write(b);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
}
4、执行方法
@RequestMapping(value = "download")
public void download(Model model, HttpServletRequest request, HttpServletResponse response) throws IOException{
String oraPath=null;
Deskmate deskmate=new Deskmate();
deskmate.setNum("13");
deskmate.setSite("北京市朝阳区");
Subject sub0=new Subject();
sub0.setCurriculum("语文");
sub0.setDuration("20");
sub0.setSegments("66");
Subject sub2=new Subject();
sub2.setSegments("12");
Subject sub3=new Subject();
sub3.setCurriculum("数学");
sub3.setDuration("88");
List<Subject> subjects=new ArrayList<>();
subjects.add(0, sub0);
subjects.add(1, new Subject());
subjects.add(2, sub2);
subjects.add(3, sub3);
User user=new User();
user.setAddress("北京市丰台区");
user.setName("哇哈哈");
user.setSex("1");
user.setDeskmate(deskmate);
user.setSubjects(subjects);
Map<String,Object> dataMap=new HashMap<>();
BeanUtils.objtomap(user,dataMap,0); //将对象转成map格式
String fileName="学生情况模板"; //文件名称
//获取Tomcat+项目名字 路径
String rootPath = new File(request.getSession().getServletContext().getRealPath("/")).getPath();
oraPath=userService.process(rootPath,fileName,dataMap); //操作模板
userService.download(oraPath, request, response); //下载文件
}
三、执行结果
代码量比较大,不一一粘贴了,有需要可以下载完整版项目(含模板),有积分的可以捧个场,没有的可以私信我、留下邮箱,我邮箱发你(可能消息回复不那么及时,见谅哦)
完整版项目及模板下载
上一篇: echarts画图/封装数据
下一篇: linux安装resin-2:部署项目