栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Springboot实现导出Word文档(包含图片)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Springboot实现导出Word文档(包含图片)

Springboot实现导出Word文档(包含图片) 准备工作

首先准备一个Word文档模板(template.docx):

准备一张图片:

查看实际效果:

开发工作

需要的相关依赖:



   org.apache.poi
   poi-ooxml
   3.17

文件导出工具类(FileExportUtil.java):

package com.kd.opt.util;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



@Component
public class FileExportUtil {

    
    public void exportWord(String path, Map params, String filename, HttpServletResponse response) throws IOException, InvalidFormatException {
        InputStream is = new FileInputStream(path);
        XWPFdocument docx = new XWPFdocument(is);
        iteraTable(params, docx);
        OutputStream os = response.getOutputStream();
        // 设置导出的内容是doc
        response.setContentType("application/octet-stream; charset=utf-8");
        response.setHeader("Content-disposition", "attachment; filename=" + filename);
        docx.write(os);
        close(os);
    }

    
    private void iteraTable(Map params, XWPFdocument doc) throws IOException, InvalidFormatException {
        List rows = null;
        List cells = null;

        List tables = doc.getTables();
        // 遍历这个word文档的所有table表格
        for (XWPFTable table : tables) {
            rows = table.getRows();

            // 遍历这个表格的所有行
            for (XWPFTableRow row : rows) {
                cells = row.getTableCells();

                // 遍历这一行的单元格
                for (XWPFTableCell cell : cells) {

                    // 判断该单元格的内容是否是字符串字段
                    if (strMatcher(cell.getText()).find()) {
                        // 替换字符串 字符串可以多行 也可以一行
                        replaceInStr(cell, params, doc);
                        continue;
                    }
                    // 判断该单元格内容是否是需要替换的图片
                    if (imgMatcher(cell.getText()).find()) {
                        // 把模板中的内容替换成图片 图片可以多张
                        replaceInImg(cell, params, doc);
                        continue;
                    }
                }
            }
        }
    }

    
    private Matcher imgMatcher(String imgstr) {
        Pattern pattern = Pattern.compile("@\{(.+?)\}");
        Matcher matcher = pattern.matcher(imgstr);
        return matcher;
    }

    
    private Matcher strMatcher(String str) {
        Pattern pattern = Pattern.compile("\$\{(.+?)\}");
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }

    
    private void replaceInStr(XWPFTableCell cell, Map params, XWPFdocument doc) {

        // 两种数据类型:一种是直接String,还有一种是List
        String key = cell.getText().substring(2, cell.getText().length() - 1);

        Integer datatype = getMapStrDataTypevalue(params, key);

        List parags = cell.getParagraphs();

        // 先清空单元格中所有的段落
        for (int i = 0; i < parags.size(); i++) {
            cell.removeParagraph(i);
        }
        if (datatype.equals(0)) {
            return;
        } else if (datatype.equals(2)) {

            // 如果类型是2 说明数据类型是List
            List strs = (List) params.get(key);
            Iterator iterator = strs.iterator();
            while (iterator.hasNext()) {
                XWPFParagraph para = cell.addParagraph();
                XWPFRun run = para.createRun();
                run.setText(iterator.next());
            }
        } else if (datatype.equals(3)) {
            String str = (String) params.get(key).toString();
            cell.setText(str);
        }
    }

    
    private void replaceInImg(XWPFTableCell cell, Map params, XWPFdocument doc) throws IOException, InvalidFormatException {
        String key = cell.getText().substring(2, cell.getText().length() - 1);
        Integer dataType = getMapImgDataType(params, key);
        List parags = cell.getParagraphs();

        // 先清空单元格中所有的段落
        for (int i = 0; i < parags.size(); i++) {
            cell.removeParagraph(i);
        }
        if (dataType.equals(0)) {
            return;
        } else if (dataType.equals(1)) {

            // 处理单张图片
            XWPFParagraph parag = cell.addParagraph();
            Map pic = (Map) params.get(key);
            insertImg(pic, parag);
        } else if (dataType.equals(2)) {

            // 处理多张图片
            List> pics = (List>) params.get(key);
            Iterator> iterator = pics.iterator();
            XWPFParagraph para = cell.addParagraph();
            Integer count = 0;
            while (iterator.hasNext()) {
                Map pic = iterator.next();

                // 图片并排插入
                if (Integer.parseInt(pic.get("style").toString()) == 1) {

                }

                // 图片竖排插入
                if (Integer.parseInt(pic.get("style").toString()) == 2) {
                    if (count > 0) {
                        para = cell.addParagraph();
                    }
                }
                insertImg(pic, para);
                count++;
            }
        }
    }

    
    private void insertImg(Map pic, XWPFParagraph para) throws IOException, InvalidFormatException {
        if (pic.get("imgPath").toString() == null) {
            return;
        }
        String picPath = pic.get("imgPath").toString();
        InputStream is = new FileInputStream(picPath);
        BufferedImage bi = ImageIO.read(new File(picPath));
        XWPFRun run = para.createRun();

        // 原图片的长宽
        Integer width = bi.getWidth();
        Integer heigh = bi.getHeight();
        Double much = 80.0 / width;

        // 图片按宽80 比例缩放
        run.addPicture(is, getPictureType(picPath.substring(picPath.lastIndexOf(".") + 1)), "", Units.toEMU(80), Units.toEMU(heigh * much));

        // 图片原长宽
//        run.addPicture(is, getPictureType(picPath.substring(picPath.lastIndexOf(".") + 1)), "", Units.toEMU(width), Units.toEMU(heigh));
        close(is);
        bi = null;
    }

    
    private Integer getMapStrDataTypevalue(Map params, String key) {
        if (params.get(key) == null) {
            return 0;
        } else if (params.get(key) instanceof List) {
            return 2;
        } else if (params.get(key) instanceof String) {
            return 3;
        } else {
            throw new RuntimeException("String Data Type Error!");
        }
    }

    
    private Integer getMapImgDataType(Map params, String key) {
        if (params.get(key) == null) {
            return 0;
        } else if (params.get(key) instanceof Map) {
            return 1;
        } else if (params.get(key) instanceof List) {
            return 2;
        } else {
            throw new RuntimeException("Image Data Type Error!");
        }
    }

    
    private int getPictureType(String picType) {
        int result = XWPFdocument.PICTURE_TYPE_PICT;
        if (picType != null) {
            if (picType.equalsIgnoreCase("png")) {
                result = XWPFdocument.PICTURE_TYPE_PNG;
            } else if (picType.equalsIgnoreCase("dib")) {
                result = XWPFdocument.PICTURE_TYPE_DIB;
            } else if (picType.equalsIgnoreCase("emf")) {
                result = XWPFdocument.PICTURE_TYPE_EMF;
            } else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {
                result = XWPFdocument.PICTURE_TYPE_JPEG;
            } else if (picType.equalsIgnoreCase("wmf")) {
                result = XWPFdocument.PICTURE_TYPE_WMF;
            }
        }
        return result;
    }

    
    private void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    
    private void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

文件导出控制器(FileExportController.java):

package com.kd.opt.controller;

import com.kd.opt.util.FileExportUtil;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
@CrossOrigin
@RequestMapping("/FileExportController")
public class FileExportController {

    @Autowired
    private FileExportUtil fileExportUtil;

    @GetMapping("/exportWord")
    public void exportWord(HttpServletResponse response) throws IOException, InvalidFormatException {
        // 模板路径
        String path = "D:\MyComputer\template.docx";
        // 传入模板的参数
        Map params = new HashMap<>();
        // 模板的导出文件名字
        String filename = "newFile.docx";

        // 一个单元格内一行字
        params.put("username", "小辰哥哥");
        params.put("sex", "男");

        // 一个单元格内多行字
        List hobby = new ArrayList<>();
        hobby.add("1、编程");
        hobby.add("2、打篮球");
        hobby.add("3、睡觉");
        params.put("hobby", hobby);

        //图片参数1 多张图片 图片多行竖排排列 style为2
        List> imgsS1List = new ArrayList<>();
        Map imgS1 = new HashMap<>();
        imgS1.put("style", 2);
        imgS1.put("imgPath", "D:\MyComputer\test.jpg");
        imgsS1List.add(imgS1);
        Map imgS2 = new HashMap<>();
        imgS2.put("style", 2);
        imgS2.put("imgPath", "D:\MyComputer\test.jpg");
        imgsS1List.add(imgS2);
        Map imgS3 = new HashMap<>();
        imgS3.put("style", 2);
        imgS3.put("imgPath", "D:\MyComputer\test.jpg");
        imgsS1List.add(imgS3);
        params.put("img1", imgsS1List);

        // 图片参数2 多张图片 一行内横排排列 style为1
        List> imgsH2List = new ArrayList<>();
        Map imgH1 = new HashMap<>();
        imgH1.put("style", 1);
        imgH1.put("imgPath", "D:\MyComputer\test.jpg");
        imgsH2List.add(imgH1);
        Map imgH2 = new HashMap<>();
        imgH2.put("style", 1);
        imgH2.put("imgPath", "D:\MyComputer\test.jpg");
        imgsH2List.add(imgH2);
        Map imgH3 = new HashMap<>();
        imgH3.put("style", 1);
        imgH3.put("imgPath", "D:\MyComputer\test.jpg");
        imgsH2List.add(imgH3);
        params.put("img2", imgsH2List);

        // 图片参数3 单张图片
        Map img3 = new HashMap<>();
        img3.put("imgPath", "D:\MyComputer\test.jpg");
        params.put("img3", img3);

        fileExportUtil.exportWord(path, params, filename, response);
    }
}

访问接口:

http://localhost:9090/OperateTicket/FileExportController/exportWord


成功:


总结

每天一个提升小技巧!!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/324484.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号