JAVA根据模板导出WPS和PowerPoint可以打开的XML

1、定义一个xml模板(注意:这个导出的实际还是个XML,使用PowerPoint打开报错,导出pptx路径:
https://blog.csdn.net/xionglangs/article/details/120365758)
一、新建一个PPT,使用WPS或office另存为XML,替换后端的参数;
文本直接替换为${map key}
在这里插入图片描述
图片,后台存储Base64二进制流blip找上面的Relationship 的ID,Target路径对应pkg:part pkg:name
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
后台代码,使用的是模板生成PPT(包含后台直接生成PPT,但需要自己调整样式:)

package com.utils;

import cn.afterturn.easypoi.entity.ImageEntity;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.io.IOUtils;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.xslf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import sun.misc.BASE64Encoder;

import java.awt.*;
import java.io.*;
import java.util.List;
import java.util.Map;

/**
 * Description:
 *
 * @Author: leo.xiong
 * @CreateDate: 2021/8/30 12:13
 * @Email: [email protected]
 * @Since:
 */
public class PptUtil {
    
    
    private static final Logger LOGGER = LoggerFactory.getLogger(PptUtil.class);
    public static final String TITLE = "title";
    /**
     * 首页内容
     */
    public static final String FIRST_CONTENT = "firstContent";
    /**
     * 首页位置 Rectangle,x轴坐标,y轴坐标,宽度,高度
     */
    public static final String ANCHOR = "anchor";
    /**
     * 图片信息
     */
    public static final String IMAGE = "image";

    public static final String CATALOG = "catalog";

    public static String exportPpt(File file, Map<String, Object> keyValueMap) {
    
    
        //创建ppt对象
        XMLSlideShow ppt = new XMLSlideShow();
        //首页
        XSLFSlide slideFirst = ppt.createSlide();
        Map<String, Object> firstValueMap = (Map<String, Object>) keyValueMap.get(FIRST_CONTENT);
        fillFirstContent(slideFirst, firstValueMap);
        //目录
        XSLFSlide slideCatalog = ppt.createSlide();
        Map<String, Object> keyCatalogMap = (Map<String, Object>) keyValueMap.get(CATALOG);
        List<XSLFSlide> contentSlides = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(keyCatalogMap)) {
    
    
            keyCatalogMap.forEach((key, content) -> {
    
    
                contentSlides.add(ppt.createSlide());
            });
        }
        fillCatalog(slideCatalog, contentSlides, keyCatalogMap);
        Map<String, List<ImageEntity>> imageEntityListMap = (Map<String, List<ImageEntity>>) keyValueMap.get(IMAGE);
        fillContent(contentSlides, keyCatalogMap, imageEntityListMap, ppt);
        StringBuffer fileUrl = new StringBuffer();
        fileUrl.append(file.getName());
        fileUrl.append(file.getName());
        FileOutputStream out = null;
        try {
    
    
            file = new File(fileUrl.toString());
            out = new FileOutputStream(file);
            ppt.write(out);
        } catch (FileNotFoundException e) {
    
    
            LOGGER.error("文件创建失败,请尝试给web目录赋权777");
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                if (out != null) {
    
    
                    out.close();
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        return file.getName();
    }

    /**
     * 填充正文,包含图片
     *
     * @param contentSlides
     * @param keyCatalogMap
     * @param imageEntityListMap
     * @param ppt
     */
    private static void fillContent(List<XSLFSlide> contentSlides, Map<String, Object> keyCatalogMap, Map<String, List<ImageEntity>> imageEntityListMap, XMLSlideShow ppt) {
    
    
        if (contentSlides != null) {
    
    
            List<String> titles = (List<String>) keyCatalogMap.get(TITLE);
            int len = contentSlides.size();
            for (int i = 0; i < len; i++) {
    
    
                createTitle(contentSlides.get(i), titles.get(i));
                List<ImageEntity> entityList = imageEntityListMap.get(titles.get(i));
                if (CollectionUtils.isEmpty(entityList)) {
    
    
                    continue;
                }
                for (ImageEntity imageEntity : entityList) {
    
    
                    createPicture(contentSlides.get(i), imageEntity.getUrl(), ppt, i);
                }
            }
        }
    }

    /**
     * 填充时间
     *
     * @param xslfSlide
     * @param picCreateTime
     */
    private static void createTime(XSLFSlide xslfSlide, String picCreateTime) {
    
    
        //标题文本框
        XSLFTextBox xslfTextBox = xslfSlide.createTextBox();
        xslfTextBox.setAnchor(new Rectangle(400, 460, 300, 80));
        xslfTextBox.setFlipHorizontal(true);
        //段落
        XSLFTextParagraph paragraph0 = xslfTextBox.addNewTextParagraph();
        paragraph0.setTextAlign(TextParagraph.TextAlign.LEFT);
        XSLFTextRun xslfTextRun = paragraph0.addNewTextRun();
        xslfTextRun.setFontSize(18D);
        //宋体 (正文)
        xslfTextRun.setFontFamily("宋体");
        String text = "123";
        xslfTextRun.setText(String.format(text, picCreateTime));
    }

    /**
     * 填充图片
     *
     * @param slide
     * @param picturePath
     * @param ppt
     * @param flag
     */
    private static void createPicture(XSLFSlide slide, String picturePath, XMLSlideShow ppt, int flag) {
    
    
        try {
    
    
            byte[] pictureData = IOUtils.toByteArray(new FileInputStream(picturePath));
            XSLFPictureData pictureIndex = ppt.addPicture(pictureData, PictureData.PictureType.JPEG);
            XSLFPictureShape pictureShape = slide.createPicture(pictureIndex);
            if (flag == 4) {
    
    
                pictureShape.setAnchor(new Rectangle(125, 100, 467, 200));
            } else {
    
    
                pictureShape.setAnchor(new Rectangle(125, 100, 467, 350));
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 目录填充
     *
     * @param xslfSlide
     * @param catalogMap
     */
    private static void fillCatalog(XSLFSlide xslfSlide, List<XSLFSlide> contentSlides, Map<String, Object> catalogMap) {
    
    
        createTitle(xslfSlide, "目录");
        //内容文本框
        XSLFTextBox xslfTextBox = xslfSlide.createTextBox();

        xslfTextBox.setAnchor((Rectangle) catalogMap.get(ANCHOR));
        xslfTextBox.setFlipHorizontal(true);
        //段落
        XSLFTextParagraph paragraph = xslfTextBox.addNewTextParagraph();
        paragraph.setTextAlign(TextParagraph.TextAlign.LEFT);
        List<String> titles = (List<String>) catalogMap.get(TITLE);
        if (CollectionUtils.isEmpty(titles)) {
    
    
            return;
        }
        for (int i = 0, len = titles.size(); i < len; i++) {
    
    
            XSLFTextRun xslfTextRun = paragraph.addNewTextRun();
            xslfTextRun.setUnderlined(true);
            xslfTextRun.setFontSize(36D);
            xslfTextRun.setFontFamily("宋体");
            xslfTextRun.setText(i + 1 + "、" + titles.get(i));
            xslfTextRun.createHyperlink().setAddress(contentSlides.get(i).toString());
        }
    }

    /**
     * 生成标题头
     *
     * @param xslfSlide
     * @param title
     */
    private static void createTitle(XSLFSlide xslfSlide, String title) {
    
    
        //标题文本框
        XSLFTextBox xslfTextBox = xslfSlide.createTextBox();
        xslfTextBox.setAnchor(new Rectangle(10, 25, 700, 85));
        xslfTextBox.setFlipHorizontal(true);
        //段落
        XSLFTextParagraph paragraph0 = xslfTextBox.addNewTextParagraph();
        paragraph0.setTextAlign(TextParagraph.TextAlign.CENTER);
        XSLFTextRun xslfTextRun = paragraph0.addNewTextRun();
        xslfTextRun.setFontSize(44D);
        //黑体
        xslfTextRun.setFontFamily("宋体");
        xslfTextRun.setBold(true);
        xslfTextRun.setText(title);
    }

    /**
     * 填充首页内容
     *
     * @param xslfSlide
     * @param firstValueMap
     */
    private static void fillFirstContent(XSLFSlide xslfSlide, Map<String, Object> firstValueMap) {
    
    
        //文本框
        XSLFTextBox xslfTextBox = xslfSlide.createTextBox();
        //坐标,x轴,y轴,宽度,高度
        xslfTextBox.setAnchor((Rectangle) firstValueMap.get(ANCHOR));
        xslfTextBox.setFlipHorizontal(true);
        //段落
        XSLFTextParagraph paragraph = xslfTextBox.addNewTextParagraph();
        paragraph.setTextAlign(TextParagraph.TextAlign.CENTER);
        //标题
        XSLFTextRun xslfTextRun = paragraph.addNewTextRun();
        xslfTextRun.setBold(true);
        xslfTextRun.setFontSize(44D);
        //宋体 (标题)
        xslfTextRun.setFontFamily("宋体");
        xslfTextRun.setText((String) firstValueMap.get(TITLE));
    }

    public static byte[] getFileToByte(File file) {
    
    
        byte[] bytes = new byte[(int) file.length()];
        try {
    
    
            InputStream is = new FileInputStream(file);
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
            byte[] bb = new byte[2048];
            int ch;
            ch = is.read(bb);
            while (ch != -1) {
    
    
                byteStream.write(bb, 0, ch);
                ch = is.read(bb);
            }
            bytes = byteStream.toByteArray();
        } catch (Exception ex) {
    
    
            ex.printStackTrace();
        }
        return bytes;
    }

    public static void main(String[] args) throws IOException {
    
    
        Map<String, Object> keyValueMap = Maps.newHashMap();
        keyValueMap.put("currentDate", "2021-09-07");
        keyValueMap.put("productSerial", "211P-DL3-1-001");
        keyValueMap.put("runTime", "2614.7");
        ImageEntity imageEntity = new ImageEntity();
        BASE64Encoder base64Encoder = new BASE64Encoder();
        imageEntity.setData(getFileToByte(new File("C:/Users/熊浪/Desktop/20210611/RESULTS/Cell_voltage_vs_Stack_current_2.jpeg")));
        //此处不一定使用imageEntity,只是需要图片的二进制byte数组,不存在二进制图片,这 keyValueMap.put("averageCellVoltageTimeImageBase64", base64EncoderValue);不添加,否则打开PPT报已损坏
        String base64EncoderValue = base64Encoder.encode(imageEntity.getData());
        keyValueMap.put("averageCellVoltageTimeImage", imageEntity);
        keyValueMap.put("averageCellVoltageTimeImageBase64", base64EncoderValue);
        keyValueMap.put("averageCellVoltageTimeImageWidth", 300);
        keyValueMap.put("averageCellVoltageTimeImageHeight", 500);

        keyValueMap.put("averageCellVoltageStackCurrentImage", imageEntity);
        keyValueMap.put("averageCellVoltageStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("averageCellVoltageStackCurrentImageWidth", 300);
        keyValueMap.put("averageCellVoltageStackCurrentImageHeight", 500);

        keyValueMap.put("upperCellVoltageStackCurrentImage", imageEntity);
        keyValueMap.put("upperCellVoltageStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("upperCellVoltageStackCurrentImageWidth", 300);
        keyValueMap.put("upperCellVoltageStackCurrentImageHeight", 500);

        keyValueMap.put("lowerCellVoltageStackCurrentImage", imageEntity);
        keyValueMap.put("lowerCellVoltageStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("lowerCellVoltageStackCurrentImageWidth", 300);
        keyValueMap.put("lowerCellVoltageStackCurrentImageHeight", 500);

        keyValueMap.put("airInletPressureStackCurrentImage", imageEntity);
        keyValueMap.put("airInletPressureStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("airInletPressureStackCurrentImageWidth", 300);
        keyValueMap.put("airInletPressureStackCurrentImageHeight", 500);

        keyValueMap.put("airMassFlowStackCurrentImage", imageEntity);
        keyValueMap.put("airMassFlowStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("airMassFlowStackCurrentImageWidth", 300);
        keyValueMap.put("airMassFlowStackCurrentImageHeight", 500);

        keyValueMap.put("anodeDpWithoutPurgeStackCurrentImage", imageEntity);
        keyValueMap.put("anodeDpWithoutPurgeStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("anodeDpWithoutPurgeStackCurrentImageWidth", 300);
        keyValueMap.put("anodeDpWithoutPurgeStackCurrentImageHeight", 500);

        keyValueMap.put("anodeDpWithPurgeStackCurrentImage", imageEntity);
        keyValueMap.put("anodeDpWithPurgeStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("anodeDpWithPurgeStackCurrentImageWidth", 300);
        keyValueMap.put("anodeDpWithPurgeStackCurrentImageHeight", 500);

        keyValueMap.put("coolantInletTemperatureStackCurrentImage", imageEntity);
        keyValueMap.put("coolantInletTemperatureStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("coolantInletTemperatureStackCurrentImageWidth", 300);
        keyValueMap.put("coolantInletTemperatureStackCurrentImageHeight", 500);

        keyValueMap.put("coolantDtStackCurrentImage", imageEntity);
        keyValueMap.put("coolantDtStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("coolantDtStackCurrentImageWidth", 300);
        keyValueMap.put("coolantDtStackCurrentImageHeight", 500);

        keyValueMap.put("hrbSpeedStackCurrentImage", imageEntity);
        keyValueMap.put("hrbSpeedStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("hrbSpeedStackCurrentImageWidth", 300);
        keyValueMap.put("hrbSpeedStackCurrentImageHeight", 500);

        keyValueMap.put("wcpSpeedStackCurrentImage", imageEntity);
        keyValueMap.put("wcpSpeedStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("wcpSpeedStackCurrentImageWidth", 300);
        keyValueMap.put("wcpSpeedStackCurrentImageHeight", 500);

        keyValueMap.put("acpSpeedStackCurrentImage", imageEntity);
        keyValueMap.put("acpSpeedStackCurrentImageBase64", base64EncoderValue);
        keyValueMap.put("acpSpeedStackCurrentImageWidth", 300);
        keyValueMap.put("acpSpeedStackCurrentImageHeight", 500);
//        exportPpt(new File("C:/Users/熊浪/Desktop/20210611/1.ppt"), keyValueMap);
        //设置模板格式和路径
        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("UTF-8");
        configuration.setDirectoryForTemplateLoading(new File("D:/IDEAWORKSPACES/master_data_service/src/main/resources/bin"));
        //读取模板路径下的PPT的.xml模板文件
        Template template = configuration.getTemplate("IDURABILITY.xml", "UTF-8");
        //设置导出路径
        File outfile = new File("C:/Users/熊浪/Desktop/20210611/test.xml");
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile)), 10240);
        try {
    
    
            //将数据替换并导出PPT
            template.process(keyValueMap, out);
        } catch (TemplateException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            out.close();
        }
    }
}

注意:
1、此处不一定使用imageEntity,只是需要图片的二进制byte数组,不存在二进制图片,这 keyValueMap.put(“averageCellVoltageTimeImageBase64”, base64EncoderValue);不添加,否则打开PPT报已损坏
2、也可以添加一个空图片占位置,防止模板样式不对

在这里插入图片描述

模板路径:https://download.csdn.net/download/xionglangs/22010357**

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xionglangs/article/details/120162098
今日推荐