欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

三、执行结果

Java动态生成模板

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

完整版项目及模板下载