import cn.afterturn.easypoi.word.WordExportUtil;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Map;

/**
 * @Author xiaoxin
 * @Date 2022/10/22 22:21
 * @Version 1.0
 */

public class ExportUtil {

    public static void export(Map<String, Object> map, String url, File tempFile) {

        try {
            XWPFDocument doc = WordExportUtil.exportWord07(url, map);
            FileOutputStream fos = new FileOutputStream(tempFile);
            doc.write(fos);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
import org.jfree.chart.*;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.*;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DefaultPieDataset;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @Author xiaoxin
 * @Date 2022/10/22 22:22
 * @Version 1.0
 */


public class JFreeChartToFileUtil {


    /***
     * 生成饼图
     * @param pds
     * @param file
     * @param title
     */
    public static void createPieChart(DefaultPieDataset pds, File file,String title) {
        try {
            // 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
            JFreeChart chart = ChartFactory.createPieChart(title, pds, false, false, true);
            // 如果不使用Font,中文将显示不出来
            Font font = new Font("宋体", Font.BOLD, 16);
            // 设置图片标题的字体
            chart.getTitle().setFont(font);
            // 得到图块,准备设置标签的字体
            PiePlot plot = (PiePlot) chart.getPlot();
            // 设置标签字体
            plot.setLabelFont(font);
            plot.setStartAngle(3.14f / 2f);

            // 设置plot的前景色透明度
            plot.setForegroundAlpha(0.7f);
            // 设置plot的背景色透明度
            plot.setBackgroundAlpha(0.0f);
            // 设置标签生成器(默认{0})
            // {0}:key {1}:value {2}:百分比 {3}:sum
            plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}{2}"));
            // 将内存中的图片写到本地硬盘
            ChartUtils.saveChartAsJPEG(file, chart, 600, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /***
     * 线状图
     * @param pds
     * @param file
     * @param title
     */
    public static void createBarChart(CategoryDataset pds, File file,String title) {
        try {
            // 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
            JFreeChart chart = ChartFactory.createBarChart(title, null,
                    null, pds, PlotOrientation.VERTICAL,
                    true, true, true);
            // 如果不使用Font,中文将显示不出来
            Font font = new Font("宋体", Font.BOLD, 12);
            // 设置图片标题的字体
            chart.getTitle().setFont(font);
            chart.getLegend().setItemFont(font);
            // 得到图块,准备设置标签的字体
            CategoryPlot plot = (CategoryPlot) chart.getPlot();
            // 设置plot的前景色透明度
            plot.setForegroundAlpha(0.7f);
            // 设置plot的背景色透明度
            plot.setBackgroundAlpha(0.0f);
            // 设置标签生成器(默认{0})

            ValueAxis rangeAxis = plot.getRangeAxis();
            CategoryAxis domainAxis = plot.getDomainAxis();

            rangeAxis.setLabelFont(font);
            rangeAxis.setTickLabelFont(font);
            domainAxis.setLabelFont(font);
            domainAxis.setTickLabelFont(font);
            domainAxis.setMaximumCategoryLabelLines(10);
            domainAxis.setMaximumCategoryLabelWidthRatio(0.5f);
            // 将内存中的图片写到本地硬盘
            ChartUtils.saveChartAsJPEG(file, chart, 600, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /***
     * 生成空心圆
     * @param pds
     * @param file
     * @param title
     */
    public static void createCircularChart(DefaultPieDataset pds, File file,String title) {

        StandardChartTheme mChartTheme = new StandardChartTheme("CN");
        // Y柱标签字体(浓度(单位:ppm))
        mChartTheme.setLargeFont(new Font("黑体", Font.BOLD, 14));
        //标题 (二氧化碳浓度趋势分析图)
        mChartTheme.setExtraLargeFont(new Font("宋体", Font.PLAIN, 20));
        //应用主题样式
        ChartFactory.setChartTheme(mChartTheme);
        //定义图标对象
        //
        JFreeChart chart = ChartFactory.createRingChart ("",// 报表题目,字符串类型
                pds, // 获得数据集
                false, // 显示图例
                false, // 不用生成工具
                false // 不用生成URL地址
        );

        Font font = new Font("宋体", Font.BOLD, 12);

        //图表
        RingPlot ringplot=(RingPlot) chart.getPlot();
        ringplot.setLabelFont(font);

        // 设置饼状图和环形图的显示数字。0代表显示文字说明,1代表显示数字,2代表显示数字以百分比的方式如果多个结合{0}:{1}
        ringplot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}:{1}"));
        ringplot.setSimpleLabels(true);

        ringplot.setBackgroundPaint(Color.WHITE);//设置背景色
        //设置简单标签
        ringplot.setSimpleLabels(true);
        //标题
        TextTitle texttitle=chart.getTitle();
        texttitle.setFont(font);
        //图示,就是点击后会弹出一个图片,显示的文字样式
//        LegendTitle legendtitle =chart.getLegend();
        //图示的标题
//        legendtitle.setItemFont(new Font("宋体", Font.BOLD, 14));
        ChartFrame mChartFrame = new ChartFrame("环形图", chart);
        mChartFrame.pack();
        //设置为true,点击请求后会弹出一个图片,设置为flase不弹出
        mChartFrame.setVisible(false);


        extracted(ringplot);

        try {
            // 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
            ChartUtils.saveChartAsJPEG(file, chart, 550, 350);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /***
     * 绘制环形图案颜色
     * @param ringplot
     */
    private static void extracted(RingPlot ringplot) {
        ringplot.setDrawingSupplier(new DefaultDrawingSupplier(
                new Paint[] {
                        new Color(46, 199, 201),
                        new Color(182, 162, 222),
                        new Color(90, 177, 239),
                        new Color(255, 185, 128),
                        new Color(226, 117, 123)
                },
                DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,
                DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,
                DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
                DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE));
    }
import cn.afterturn.easypoi.entity.ImageEntity;
import io.ctc.commons.tools.utils.Result;
import io.ctc.commons.tools.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 统计报表Controller
 *
 * @author sunmingwei
 * @version 2021-05-25
 */
@Slf4j
@RestController
@RequestMapping("test")
public class TestController {






    @RequestMapping("export")
    public void export(HttpServletResponse response) throws IOException {
        response.setContentType("application/msword");
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("测试.docx", StandardCharsets.UTF_8.name()));
        OutputStream outputStream = response.getOutputStream();

        Map<String, Object> map = new HashMap<>();
        putBaseInfo(map);
        putImg(map);
        putList(map);
        putBar(map);


        String url =  Objects.requireNonNull(getClass().getClassLoader().getResource("export.docx")).getPath();
        File tempFile = File.createTempFile("tempDoc", ".docx");
        ExportUtil.export(map, url, tempFile);

        InputStream in = new FileInputStream(tempFile);

        //创建存放文件内容的数组
        byte[] buff = new byte[1024];
        //所读取的内容使用n来接收
        int n;
        //当没有读取完时,继续读取,循环
        while ((n = in.read(buff)) != -1) {
            //将字节数组的数据全部写入到输出流中
            outputStream.write(buff, 0, n);
        }
        //强制将缓存区的数据进行输出
        outputStream.flush();
        //关流
        outputStream.close();
        in.close();
        tempFile.deleteOnExit();

    }


    private void putBaseInfo(Map<String, Object> map) {
        map.put("theme", "集中化测试平台");
        map.put("nowDate",new SimpleDateFormat("yyyyMMdd").format(new Date()));
        map.put("person", "1、\t缺陷概览");
        map.put("title1", "2、\t缺陷等级分布");
        map.put("title2", "1)\t缺陷等级分布图");
        map.put("title3", "2)\t缺陷等级分布列表");
    }

    /***
     * 部分图像数据负责的,由前端传base64过来直接转图片
     * @param map
     */
    private void putImg(Map<String, Object> map) {
        ImageEntity image = getImage(str);
        map.put("img1", image);
    }

    /***
     * 环形图数据
     * @param map
     * @throws IOException
     */
    private void putBar(Map<String, Object> map) throws IOException {
        File file2 = File.createTempFile("temp", "jpg");
        DefaultPieDataset pds = new DefaultPieDataset();
        pds.setValue("建议", 100);
        pds.setValue("轻微", 100);
        pds.setValue("一般", 300);
        pds.setValue("严重", 400);
        pds.setValue("致命", 500);
        JFreeChartToFileUtil.createCircularChart(pds, file2, "1)缺陷等级分布图");
        ImageEntity image = new ImageEntity();
        image.setHeight(350);
        image.setWidth(550);
        image.setUrl(file2.getAbsolutePath());
        image.setType(ImageEntity.URL);
        map.put("img2", image);
    }




    private void putList(Map<String, Object> map) {
        List<Map<String, String>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Map<String, String> map1 = new HashMap<>();
            map1.put("name", "xiao");
            map1.put("age", "12");

            list.add(map1);
        }

        map.put("list", list);
    }

    private ImageEntity getImage(String base64CodeStr){
        if (StringUtils.isBlank(base64CodeStr)){
            return null;
        }
        ImageEntity image = new ImageEntity();
        image.setHeight(150);
        image.setWidth(550);
        base64CodeStr = base64CodeStr.replaceAll("data:image/png;base64,","");
        try {
            BASE64Decoder decode = new BASE64Decoder();
            byte[] b = decode.decodeBuffer(base64CodeStr.trim());
            image.setData(b);
        } catch (IOException e) {
            e.printStackTrace();
        }
        image.setType(ImageEntity.Data);
        return image;
    }



    public static String str = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAzwAAAD6CAYAAABkr0LaAAAAAXNSR0IArs4c6QAAIABJREFUeF7svQeUXFeVtv1Wzl1VnbuVs6xkReeEg2yDE2AbGweMBzCGf2BgmPnmm1mzhvlmhv9nfQMMDOAAOJIZHDFgWTa2ZDnIClbOWercFbpy/tc+rdu6XV1VXdVd4VbVvmt5YavvPfec5xyJ+2rv/W5VKpVKgS8mwASYABNgAkyACTABJsAEmEANElCx4KnBXeUlMQEmwASYABNgAkyACTABJiAIsODhg8AEmAATYAJMgAkwASbABJhAzRJgwVOzW8sLYwJMgAkwASbABJgAE2ACTIAFD58BJsAEmAATYAJMgAkwASbABGqWAAuemt1aXhgTYAJMgAkwASbABJgAE2ACLHj4DDABJsAEmAATYAJMgAkwASZQswRY8NTs1vLCmAATYAJMgAkwASbABJgAE2DBw2eACTABJsAEmAATYAJMgAkwgZolwIKnZreWF8YEmAATYAJMgAkwASbABJgACx4+A0yACTABJsAEmAATYAJMgAnULAEWPDW7tbwwJsAEmAATYAJMgAkwASbABFjw8BlgAkyACTABJsAEmAATYAJMoGYJsOCp2a3lhTEBJsAEmAATYAJMgAkwASbAgofPABNgAkyACTABJsAEmAATYAI1S4AFT81uLS+MCTABJsAEmAATYAJMgAkwARY8fAaYABNgAkyACTABJsAEmAATqFkCLHhqdmt5YUyACTABJsAEmAATYAJMgAmw4OEzwASYABNgAkyACTABJsAEmEDNEmDBU7NbywtjAkyACTABJsAEmAATYAJMgAUPnwEmwASYABNgAkyACTABJsAEapYAC56a3VpeGBNgAkyACTABJsAEmAATYAIsePgMMAEmwASYABNgAkyACTABJlCzBFjw1OzW8sKYABNgAkyACTABJsAEmAATYMHDZ4AJMAEmwASYABNgAkyACTCBmiXAgqdmt5YXxgSYABNgAkyACTABJsAEmAALHj4DTIAJMAEmwASYABNgAkyACdQsARY8Nbu1vDAmwASYABNgAkyACTABJsAEWPDwGWACTIAJMAEmwASYABNgAkygZgmw4KnZreWFMQEmwASYABNgAkyACTABJsCCh88AE2ACTIAJMAEmwASYABNgAjVLgAVPzW4tL4wJMAEm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";

}
<!--word导出需要的依赖-->
        <dependency>
            <groupId>org.jfree</groupId>
            <artifactId>jfreechart</artifactId>
            <version>1.5.3</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.4.0</version>
        </dependency>
        <!--word导出需要的依赖-->

还有一个模板!这里上传不了啊,我只是自己记录,需要的人再找我吧

Java 导出word 附带多张图片 java导出word带图表_Java 导出word 附带多张图片

这个工具有弊端,我后面遇到了很多问题,下面看图:

1.windows正常导出,但linux报错,不知道什么原因。按照网上说的,windows需要把java.awt.headless设置为false,在linux的话设置为true,设置来设置去咱也没解决,下面是报错截图

Java 导出word 附带多张图片 java导出word带图表_Java 导出word 附带多张图片_02

Java 导出word 附带多张图片 java导出word带图表_java_03

 

Java 导出word 附带多张图片 java导出word带图表_spring_04

后来搞了几天都没解决,后来想了一个方法,从前端传base64值过来直接添加进去,但这里也有坑,你会在日志中看到各种问题,例如找不到路径、找不到文件、找不到模板的等问题,因为我是Springboot,线上发布只有一个jar包,并不像那些tomcat一样,所以当你用Classloader.getResourcesAsStream("classpath:/template/export.docx")去获取模板路径的时候绝对会报错。所以下面的代码我将InputStream转成MyXWPFDocument对象了,然后再进行操作就可以了。下面看最新代码:

@PostMapping("/word")
    public void export(@RequestBody WordExportRequestDto wordExportDto, HttpServletResponse response) throws Exception {

        //根据项目id获取数据,也就是页面上获取的数据,转成entity
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("projectId",wordExportDto.getProjectId());
        Map<String, Object> stringObjectMap = projectOverviewService.defectTopData(hashMap);
        String json = GsonUtils.GsonString(stringObjectMap);
        WordDataDto wordDataDto = GsonUtils.GsonToBean(json, WordDataDto.class);

        //查询出项目名称数据
        ProjectBaseinfoDto projectInfo = projectInfoDao.selectByIdProjectInfo(wordExportDto.getProjectId());

        String fileName = projectInfo.getName() + "项目概览-缺陷详情";
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-Type", "application/msword");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName+".docx", StandardCharsets.UTF_8.name()));

        List<DefectStatusSpreadDto> defectStatusSpread = defectInfoService.getDefectStatusSpread(hashMap);

        //根据项目id获取缺陷列表
        List<String> list = new ArrayList<>();
        list.add(wordExportDto.getProjectId().toString());
        List<DefectInfoDto> defectByProjectIdList = defectInfoService.getDefectByProjectIdListCopy(list);


        Map<String, Object> map = new HashMap<>();
        map.put("defectSurveyPic",wordExportDto.getDefectSurveyPic());

        //添加大标题、小标题等信息
        putBaseInfo(map,projectInfo);
        //添加图片信息,此图片信息是前端传过来的base64
        putImg(map,wordExportDto);
        //添加缺陷等级分布列表数据
        putList(map,wordDataDto);

        //缺陷状态分布列表数据
        putDefectStatusList(map,defectStatusSpread);

        //缺陷列表数据,最下面的一张图
        putGetDefectList(map,defectByProjectIdList);

        //将流转换成word对象
        InputStream inputStream = ResourceUtil.getStream("classpath:template/export.docx");
        MyXWPFDocument doc = new MyXWPFDocument(inputStream);

        //导出word并指定word导出模板
        WordExportUtil.exportWord07(doc, map);
        //设置编码格式
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        //设置内容类型
        response.setContentType("application/octet-stream");

        //设置头及文件命名。
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("测试.docx", StandardCharsets.UTF_8.name()));

        //写入
        doc.write(response.getOutputStream());
    }



    private void putBaseInfo(Map<String, Object> map,ProjectBaseinfoDto projectBaseinfoDto) {
        map.put("theme", projectBaseinfoDto.getName());
        map.put("nowDate",new SimpleDateFormat("yyyyMMdd").format(new Date()));
        map.put("person", "1、\t缺陷概览");
        map.put("title1", "2、\t缺陷等级分布");
        map.put("title2", "1)\t缺陷等级分布图");
        map.put("title3", "2)\t缺陷等级分布列表");
        map.put("title4", "3、\t缺陷状态分布");
        map.put("title5", "1)\t缺陷状态分布图");
        map.put("title6", "2)\t缺陷状态分布列表");
        map.put("title7", "4、\t缺陷列表");
    }

    /***
     * 部分图像数据负责的,由前端传base64过来直接转图片
     * @param map
     */
    private void putImg(Map<String, Object> map,WordExportRequestDto wordExportDto) {

        //顶部图
        if (Objects.nonNull(wordExportDto.getDefectSurveyPic())){
            ImageEntity image = getImage(map.get("defectSurveyPic").toString());
            map.put("img1", image);
        }

        //环形图数据 缺陷等级分布图
        if (Objects.nonNull(wordExportDto.getDefectLevelPic())){
            ImageEntity image = getImage(map.get("defectLevelPic").toString());
            map.put("img2", image);
        }

        //环形图数据 缺陷状态分布图
        if (Objects.nonNull(wordExportDto.getDefectStatusPic())){
            ImageEntity image = getImage(map.get("defectStatusPic").toString());
            map.put("img3", image);
        }
    }


    /***
     *  添加缺陷等级分布列表数据
     * @param map
     * @param wordDataDto
     */
    private void putList(Map<String, Object> map,WordDataDto wordDataDto) {
        List<Map<String, String>> list = new ArrayList<>();

        WordDefectLevelDto defectLevel = wordDataDto.getDefectLevel();
        if (Objects.nonNull(defectLevel)){
            List<WordTableDataDto> tableData = defectLevel.getTableData();
            if (!tableData.isEmpty()){
                for (WordTableDataDto dto : tableData){
                    Map<String, String> map1 = new HashMap<>();
                    map1.put("level", dto.getDefectLevel());
                    map1.put("defectCount", dto.getDefectCount());
                    map1.put("suspend", dto.getSuspend());
                    map1.put("moreThreeDaysRepair", dto.getThreeDaysRepair());
                    map1.put("repair", dto.getRepair());
                    map1.put("newTodays", dto.getNewTodays());
                    map1.put("rate", dto.getRate());
                    map1.put("twoDaysRepair", dto.getTwoDaysRepair());
                    map1.put("threeDaysRepair", dto.getThreeDaysRepair());
                    map1.put("closed", dto.getClosed());
                    map1.put("toVerified", dto.getToVerified());
                    list.add(map1);
                }
            }
        }

        map.put("list", list);
    }


    /***
     * 	缺陷状态分布列表数据
     * @param map
     * @param defectStatusSpread
     */
    private void putDefectStatusList(Map<String, Object> map,List<DefectStatusSpreadDto> defectStatusSpread) {

        //计算出总和
        IntSummaryStatistics repairTotal = defectStatusSpread.stream().mapToInt((x) -> Math.toIntExact(x.getCount())).summaryStatistics();

        List<Map<String, String>> list = new ArrayList<>();
            if (!defectStatusSpread.isEmpty()){
                for (DefectStatusSpreadDto dto : defectStatusSpread){
                    Map<String, String> map1 = new HashMap<>();
                    map1.put("statusName", dto.getStatusName());
                    map1.put("count", dto.getCount().toString());

                    //转换百分比
                    BigDecimal a = new BigDecimal(dto.getCount());
                    BigDecimal b = new BigDecimal(repairTotal.getSum());
                    int rate = NumberUtil.div(a, b,2).multiply(BigDecimal.valueOf(100)).intValue();
                    map1.put("rate", rate+"%");
                    list.add(map1);
                }
            }
        map.put("list2", list);
        }


    /***
     * 获取缺陷列表数据,最下面的表格
     * @param map
     * @param defectByProjectIdList
     */
    private void putGetDefectList(Map<String, Object> map,List<DefectInfoDto> defectByProjectIdList) {
        List<Map<String, String>> list = new ArrayList<>();

            if (!defectByProjectIdList.isEmpty()){
                int num = 0;
                for (int i = 0;i < defectByProjectIdList.size();i++){
                    num++;
                    Map<String, String> map1 = new HashMap<>();
                    map1.put("id", num+"");
                    map1.put("number", defectByProjectIdList.get(i).getDefectCode());
                    map1.put("defectName", defectByProjectIdList.get(i).getName());
                    if (Objects.nonNull(defectByProjectIdList.get(i).getDefectEnv())){
                        map1.put("dev", initializationEnv(defectByProjectIdList.get(i).getDefectEnv()));
                    }
                    if (Objects.nonNull(defectByProjectIdList.get(i).getDefectLevel())){
                        map1.put("level", initializationDefectLevel(defectByProjectIdList.get(i).getDefectLevel()));
                    }
                    if (Objects.nonNull(defectByProjectIdList.get(i).getDefectType())){
                        map1.put("type", initializationDefectType(defectByProjectIdList.get(i).getDefectType()));
                    }
                    map1.put("createator",defectByProjectIdList.get(i).getCreatorName());
                    map1.put("date", new SimpleDateFormat("yyyy-MM-dd").format(defectByProjectIdList.get(i).getCreateDate()));
                    list.add(map1);
                }

            }

        map.put("list3", list);
    }





    /***
     * 将base64封装成ImageEntity对象
     * @param base64CodeStr
     * @return
     */
    private ImageEntity getImage(String base64CodeStr){
        if (StringUtils.isBlank(base64CodeStr)){
            return null;
        }
        ImageEntity image = new ImageEntity();
        image.setHeight(150);
        image.setWidth(550);
        base64CodeStr = base64CodeStr.replaceAll("data:image/png;base64,","");
        try {
            BASE64Decoder decode = new BASE64Decoder();
            byte[] b = decode.decodeBuffer(base64CodeStr.trim());
            image.setData(b);
        } catch (IOException e) {
            e.printStackTrace();
        }
        image.setType(ImageEntity.Data);
        return image;
    }

,但问题又来了,前端传base64到后端,前端生成base64很慢,很不理想。仅作为自己参考