java动态生成word以及下载到本地或者浏览器下载

java动态生成word以及下载到本地或者浏览器下载

我选择的是freemaker

首先看一下图:
在这里插入图片描述
经过多重查找和对比,最终选择了xml这种模板形式。其实可能poi大家会更熟悉一些,但是它缺点是样式需要通过代码去一行一行写,这样写出来,复杂程度太高,而且样式还不好看。

word操作

将对应的文字用占位符(${})来替代
在这里插入图片描述
下面这个图大家要仔细看,下面是个动态的表格。就是这个 ${three}-> ${four} -> 列表是根据数据库有多少数据动态生成的
在这里插入图片描述

打开word,点击文件wps文字----》另存为—》保存为xml格式
在这里插入图片描述

在这里插入图片描述
最后将xml文件直接修改为ftl后缀
在这里插入图片描述
将文件放入项目中,如下图(其实这个ftl放的位置以及读取方法有三种,下面会一一介绍)
在这里插入图片描述

具体代码

@Override
    public Result generateWord(int type, String code, HttpServletResponse resp) {
        List<Engineering> engineeringList=new ArrayList<>();
        Result result=new Result();
        Map<String,Object> data=new HashMap<>();
        String change;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        if (type==1){
            Inventory inventory=this.wordgenerateMapper.selectInByCode(code);
            if (inventory==null){
                result.setState("0");
                result.setMessage("没有对应清册");
                result = Result.ERROR();
                return result;
            }
            data.put("one",inventory.getName());
            data.put("two",format.format(inventory.getCreateDate()));
            change="清册编码为"+code+"的主要设备材料表";
            //清册工程下所有对应id所有数据
            engineeringList=this.wordgenerateMapper.selectEngAllByIn(code);
            for (int i=0;i<engineeringList.size();i++){
                Engineering tempEn=engineeringList.get(i);
                List<Inventory> inventoryList=this.wordgenerateMapper.selectInvAll(tempEn);
                engineeringList.get(i).setInventoryList(inventoryList);
                for (int j=0;j<inventoryList.size();j++){
                    Inventory tempIn=inventoryList.get(i);
                    List<Material> materialList=this.wordgenerateMapper.selectMatAll(tempIn.getId());
                    inventoryList.get(i).setMaterialList(materialList);
                }
            }
        }else if (type==2){
            Engineering engineering=this.wordgenerateMapper.selectEnByCode(code);
            if (engineering==null){
                result.setState("0");
                result.setMessage("没有对应工程");
                result = Result.ERROR();
                return result;
            }
            data.put("one",engineering.getName());
            data.put("two",format.format(engineering.getCreateDate()));
            change="工程编码为"+code+"的主要设备材料表";
            //工程下所有对应id所有数据
            engineeringList=this.wordgenerateMapper.selectEngAll(code);
            for (int i=0;i<engineeringList.size();i++){
                Engineering tempEn=engineeringList.get(i);
                List<Inventory> inventoryList=this.wordgenerateMapper.selectInvAll(tempEn);
                engineeringList.get(i).setInventoryList(inventoryList);
                for (int j=0;j<inventoryList.size();j++){
                    Inventory tempIn=inventoryList.get(i);
                    List<Material> materialList=this.wordgenerateMapper.selectMatAll(tempIn.getId());
                    inventoryList.get(i).setMaterialList(materialList);
                }
            }
        }else{
            Project project=this.wordgenerateMapper.selectPrByCode(code);
            if (project==null){
                result.setState("0");
                result.setMessage("没有对应项目");
                result = Result.ERROR();
                return result;
            }
/**
*这两个data里面put的one和two值用来替换到模板中${one},${two的位置}
*/              
            data.put("one",project.getName());
            data.put("two",format.format(project.getCreateDate()));
            change="项目编码为"+code+"的主要设备材料表";
            //项目对应工程下所有对应id所有数据
            engineeringList=this.wordgenerateMapper.selectEngAllByProject(code);
            for (int i=0;i<engineeringList.size();i++){
                Engineering tempEn=engineeringList.get(i);
                Inventory tempdata=new Inventory();
                tempdata.setId(code);
                tempdata.setEngineeringId(tempEn.getId());
                tempdata.setEngineeringCode(tempEn.getCode());
                tempdata.setEngineeringName(tempEn.getName());
                List<Inventory> inventoryList=this.wordgenerateMapper.selectInvAllByOnly(tempdata);
                engineeringList.get(i).setInventoryList(inventoryList);
                for (int j=0;j<inventoryList.size();j++){
                    Inventory tempIn=inventoryList.get(i);
                    List<Material> materialList=this.wordgenerateMapper.selectMatAll(tempIn.getId());
                    inventoryList.get(i).setMaterialList(materialList);
                }
            }
        }
/**
*这个ontdata就是ftl第一个list中的集合数据
*/           
        data.put("onedata",engineeringList);
        //configuration.setClassForTemplateLoading(UserServiceImpl.class, "/templates"); // FTL文件所存在的位置
        //configuration.setServletContextForTemplateLoading(ClassLoader.getSystemClassLoader(),"/templates");
/**
*下面这个是从resource下读取文件,里面/templates代表 resource下的templates文件夹下的文件
*/        configuration.setClassLoaderForTemplateLoading(ClassLoader.getSystemClassLoader(),"/templates");
        try {
/**
*下面这个是去对应路径下找到code22.ftl模板文件
*/       
        template = configuration.getTemplate("code22.ftl");
        Writer out=null;
        String urlTest1=URLEncoder.encode(change, "UTF-8");
        //定义下载的类型,标明是word文件(这种是浏览器下载的方式)
        resp.setContentType("APPLICATION/OCTET-STREAM");
/**
*URLEncoder.encode是中文解码用的(防止乱码)
*/         
        resp.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(change, "UTF-8")+ ".doc");
/**
*下面注释的是下载到本地对应盘符的方式
*/             
//        File outFile = new File(tempDir+ change+".docx");
//        File outFile = new File("D:/Config/"+ change+".docx");
//            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
            out = new BufferedWriter(new OutputStreamWriter(resp.getOutputStream(),"UTF-8"));
/**
*template.process这个是模板的核心,将你需要替换的值data(Map类型)和out(Writer字符输出流)出入进去
*/             
            template.process(data, out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.setState("1");
        result.setMessage("生成成功");
        result = Result.SUCCESS();
        return result;
    }

ftl文件结构

占位符 ${one}、 ${two}的位置,跟之前修改word位置那里是对应的
在这里插入图片描述在这里插入图片描述
下面是动态生成数据以及标题的地方
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面图我嵌套了3层list循环(顺序就好像这个线的顺序 红-》黄-》绿)
在这里插入图片描述

补充:关于list或者数据为空的情况怎么解决
数据为空
在这里插入图片描述
集合为空
在这里插入图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值