java根据模板生成word

这篇博客详细介绍了如何使用FreeMarker模板和Java来生成Word文档。首先,创建并转换Word为XML格式,然后将文件后缀改为.ftl作为模板。在代码中,填充数据到模板中,并在项目resource下的template文件夹存储。通过替换tb占位符,将内容插入模板,生成临时文件并返回给前端下载。此外,还展示了如何处理图片尺寸以适应Word的布局需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 首先需要生成模板
    创建word文档
    在这里插入图片描述

将word另存为 xml格式
将文档后缀改成ftl
2. 代码填充xxx
将生产的模板放在项目resource下建立一个template文件夹
将需要填充的内容用tb替换

 public void exportTongzhishu(HttpServletRequest request, HttpServletResponse response) {
        InputStream in = null;
        OutputStream out = null;
        try {
            //获得一条数据,填充到map中
            int id = Integer.parseInt(request.getParameter("id"));
            User model = UserJPA.getById(id);
            Map<String, Object> dataMap = new LinkedHashMap<>();
            getDataFroTongzhishu(dataMap, model);
            String templateFilePath = "";
                templateFilePath = ResourceUtils.getFile("classpath:template").getPath() + "/tongzhidan.ftl";
            //在模板文件里插入数据后生成了一个临时文件,再把这个临`时文件用流返回`给前端
            String exportFilePath = "C:\\ebo_system_file\\template\\tongzhidan\\";
            File file = new File(exportFilePath);
            if (!file.exists() && !file.isDirectory()) {
                file.mkdirs();
            }
            exportFilePath += "tongzhidan-临时文件-" + System.currentTimeMillis() + ".doc";
            //设置response返回信息
            response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode("通知单", "UTF-8"))));

            //得到填充数据后的文件,返回给前端
            File newFile = ExportDotFile.getInstance().createDocFile(templateFilePath, dataMap, exportFilePath, 1);

            in = new FileInputStream(newFile);//获取文件输入流
            int len = 0;
            byte[] buffer = new byte[1024];
            out = response.getOutputStream();
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);//将缓冲区的数据输出到客户端浏览器
            }
            out.flush();
            out.close();
            in.close();
//            newFile.delete();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            logger.error("导出异常", e);
        } finally {
            try {
                if (null != in) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
public static void getDataFroTongzhishu(Map<String, Object> dataMap, User model) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日");
        dataMap.put("tb1", model.getname() == null ? "" : changeStr(model.getOffendPeople()));
        dataMap.put("tb2", model.getNumber() == null ? "" : changeStr(model.getNumber()));
        Date happenDate = sdf.parse(model.getHappenDate());
        dataMap.put("tb3", sdf1.format(happenDate));
        dataMap.put("tb4", model.getBehaviorDescription() == null ? "" : changeStr(model.getBehaviorDescription()));
        dataMap.put("tb5", model.getSystemName() == null ? "" : changeStr(model.getSystemName()));
        dataMap.put("tb6", model.getSystemNumber() == null ? "" : changeStr(model.getSystemNumber()));
        dataMap.put("tb7", model.getVersionNumber() == null ? "" : changeStr(model.getVersionNumber()));
        //word文档里的图片宽度需求是14厘米,像素宽度大概是400pt,高度根据 原图片/400 比值重新赋值
        if (!Strings.isNullOrEmpty(model.getBehaviorDescriptionUrl())) {
            Map map = getImageSize(model.getBehaviorDescriptionUrl());
            double width = Integer.valueOf(map.get("width").toString());
            double height = Integer.valueOf(map.get("height").toString());
            double newHeight = 400 / width * height;
            dataMap.put("tb8", getImageBase(model.getBehaviorDescriptionUrl()));
            dataMap.put("tb8_width", "400pt");
            dataMap.put("tb8_height", newHeight + "pt");
        } else {
//            dataMap.put("tb20", "");
        }
    }

ExportDotFile文件

public class ExportDotFile {
    private static Logger logger = LoggerFactory.getLogger(ExportDotFile.class);

    private static ExportDotFile service = null;

    private ExportDotFile() {
        super();
    }

    public static ExportDotFile getInstance() {
        if(service == null) {
            service = new ExportDotFile();
        }
        return service;
    }



    /**
     *
     * @param templateFilePath  eg: /template/test/test.ftl
     * @param dataMap
     * @param exportFilePath  eg: /tmp/test/test123.doc
     * @param loadType  设置路径加载方式。1-绝对路径,2-项目相对路径
     * @return
     * @throws Exception
     */
    public File createDocFile(String templateFilePath, Map<String, Object> dataMap, String exportFilePath, int loadType) {
        Template t = null;
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
        configuration.setDefaultEncoding("UTF-8");
        Writer out = null;
        FileOutputStream fos = null;
        OutputStreamWriter oWriter =null;
        File outFile = new File(exportFilePath);
        try {
            templateFilePath = pathReplace(templateFilePath);
            String ftlPath = templateFilePath.substring(0, templateFilePath.lastIndexOf('/'));
            if (loadType == 1) {
                configuration.setDirectoryForTemplateLoading(new File(ftlPath)); // FTL文件所存在的位置
            } else {
                configuration.setClassForTemplateLoading(this.getClass(), ftlPath);//以类加载的方式查找模版文件路径
            }

            String ftlFile = templateFilePath.substring(templateFilePath.lastIndexOf('/') + 1);
            t = configuration.getTemplate(ftlFile); // 模板文件名
             fos = new FileOutputStream(outFile);
             oWriter = new OutputStreamWriter(fos, "UTF-8");
            out = new BufferedWriter(oWriter);

            t.process(dataMap, out);
            oWriter.flush();
            out.flush();
            oWriter.close();
        } catch (Exception e) {
            logger.error("导出word文档出错", e);
        }finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (null !=fos){
                    fos.close();
                }
                if (null !=oWriter){
                    oWriter.close();
                }
            } catch (IOException e) {
                logger.error("关闭Write对象出错", e);
            }
        }
        return outFile;
    }

    /**
     *  把路径的\替换成/
     * @param path
     * @return
     */
    private String pathReplace(String path) {
        while(path != null && path.contains("\\")) {
            path = path.replace("\\", "/");
        }
        return path;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值