Java动态生成模板

逻辑

(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); //下载文件
	}
	

三、执行结果

代码量比较大,不一一粘贴了,有需要可以下载完整版项目(含模板),有积分的可以捧个场,没有的可以私信我、留下邮箱,我邮箱发你(可能消息回复不那么及时,见谅哦)

完整版项目及模板下载

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值