SpringBoot使用freemarker动态生成word文档

最近做项目有个需求,在动态生成word文档的同时插入电子签名图片,这里使用freemarker来实现。

首先引入freemarker依赖:



	org.freemarker
	freemarker
	2.3.28

首先模板要自己先画好,打开word自己制作一个模板:

SpringBoot使用freemarker动态生成word文档_第1张图片

然后将它另存为xml,修改相关内容后再另存为ftl文件,这样就可以使用了(抓取重要的几个部分)

//如果想要打出多个要是用list标签
<#list signs as sign>

....
//文字部分的替换

	
		
		
		
		
		
		
	
	作战部队:${sign.army}

...
//图片部分(二维码也是一样的)
<#if (sign.signImage != "")>

	${sign.signImage}
	
		
		
		
		
		
		
	


...

项目结构大致如下:

SpringBoot使用freemarker动态生成word文档_第2张图片

编写一个文件处理工具类:

@Component
public class DocumentUtil {
   /**
     * 生成word或excel文件
     * @param dataMap word或excel中需要展示的动态数据,用map集合来保存
     * @param templateName word或者excel模板名称,例如:test.ftl
     * @param fileFullPath 要生成的文件全路径
     */
    @SuppressWarnings("unchecked")
    public static void createWordOrExcel(Map dataMap, String templateName, String fileFullPath) {
        logger.info("[createWord]:==>方法进入");
        logger.info("[fileFullPath]:==>" + fileFullPath);
        logger.info("[templateName]:==>" + templateName);

        try {
            // 创建配置实例
            Configuration configuration = new Configuration();
            logger.info("[创建配置实例]:==>");

            // 设置编码
            configuration.setDefaultEncoding("UTF-8");
            logger.info("[设置编码]:==>");

            // 设置处理空值
            configuration.setClassicCompatible(true);

            // 设置ftl模板文件加载方式
            configuration.setClassForTemplateLoading(DocumentUtil.class,"/template/ftl");

            //创建文件
            File file = new File(fileFullPath);
            // 如果输出目标文件夹不存在,则创建
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }

            // 将模板和数据模型合并生成文件
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
            // 获取模板
            Template template = configuration.getTemplate(templateName);
            // 生成文件
            template.process(dataMap, out);

            // 清空缓存
            out.flush();
            // 关闭流
            out.close();

        } catch (Exception e) {
            logger.info("[生成word或excel文件出错]:==>" + e.getMessage());
            e.printStackTrace();
        }
    }
}

二维码和图片的工具类:

public class QRCodeUtil {

    /**
     * 生成BASE64格式的二维码
     * @param contents
     * @param width
     * @param height
     * @return
     */
    public static String creatRrCode(String contents, int width, int height) {
        String binary = null;
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
            // 1、读取文件转换为字节数组
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            BufferedImage image = toBufferedImage(bitMatrix);
            //转换成png格式的IO流
            ImageIO.write(image, "png", out);
            byte[] bytes = out.toByteArray();

            // 2、将字节数组转为二进制
            binary = new String(Base64.encodeBase64(bytes));
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return binary;
    }

    /**
        * image流数据处理
        */
    public static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        return image;
    }


    /**
     * 根据图片url转成图片文件
     * @param url
     * @return
     */
    public static File dealUrlToImage(String url) {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        BufferedOutputStream stream = null;
        InputStream inputStream = null;
        File file = null;
        try {
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            inputStream = conn.getInputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }
            file = File.createTempFile("pattern", "." + "jpg");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            stream = new BufferedOutputStream(fileOutputStream);
            stream.write(outStream.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (stream != null) {
                    stream.close();
                }
                outStream.close();
            } catch (Exception e) {
            }
            return file;
        }
    }

    public static String getImageStr(String imgFile){
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }

}

controller

@Api(tags = "文件管理")
@RestController
@RequestMapping("/document")
public class FileController {
    @ApiOperation(value="生成word文件测试")
    @RequestMapping(value = "/createWord", method = RequestMethod.POST)
    public String createWord() throws IOException {
        Map resultMap = new HashMap<>();
        List> mapList = new ArrayList<>();
        Map map1 = new HashMap<>();
        map1.put("army", "八路军独立团一营");
        map1.put("speciality", "三八大盖");
        File file = QRCodeUtil.dealUrlToImage("这里是你想要的图片的地址");
        map1.put("signImage", QRCodeUtil.getImageStr(file.getAbsolutePath()));
        map1.put("img", QRCodeUtil.creatRrCode("20201986606-001-sfasfasfsdgfs", 100, 100));
        mapList.add(map1);
        Map map2 = new HashMap<>();
        map2.put("army", "八路军独立团二营");
        map2.put("speciality", "意大利炮");
        map2.put("signImage", QRCodeUtil.getImageStr(file.getAbsolutePath()));
        map2.put("img", QRCodeUtil.creatRrCode("20201986606-002-sdsdafafafasafa", 100, 100));
        mapList.add(map2);
        resultMap.put("signs", mapList);

        //模板名称
        String templateName = "签名.ftl";
        String fileFullPaths = "C:\\Users\\Administrator\\Desktop\\电子签名.docx";

        DocumentUtil.createWordOrExcel(resultMap,templateName, fileFullPaths);
        return "操作成功!";
    }
}

最终结果展示SpringBoot使用freemarker动态生成word文档_第3张图片

如果你要生产成excel步骤也是和上面一样的

你可能感兴趣的:(SpringBoot,spring,boot,java,后端)