Maybe 发表于 2024-6-21 17:36:51

PPT导出-模板和自定义处理方案

本帖最后由 Maybe 于 2024-6-21 17:38 编辑

​ 两种方式:1.自定义样式导出2.根据模板导出
1.自定义设置样式导出PPT

   public static void main(String[] args) throws IOException {
      XMLSlideShow ppt = new XMLSlideShow();
      // 创建幻灯片
      XSLFSlide slide = ppt.createSlide();

      // 创建文本框
      XSLFTextBox textBox = slide.createTextBox();
      // x y设置距离w h 设置大小
      textBox.setAnchor(new Rectangle2D.Double(30,0, 600, 50));
      // 设置文本框的内容
      textBox.addNewTextParagraph().addNewTextRun().setText("姓名");


      // 创建文本框
      XSLFTextBox textBox1 = slide.createTextBox();
      // x y设置距离w h 设置大小
      textBox1.setAnchor(new Rectangle2D.Double(30,50, 600, 50));
      // 设置文本框的内容
      textBox1.addNewTextParagraph().addNewTextRun().setText("年龄");
      // 创建文本框
      XSLFTextBox textBox11 = slide.createTextBox();
      // x y设置距离w h 设置大小
      textBox11.setAnchor(new Rectangle2D.Double(250,50, 600, 50));
      // 设置文本框的内容
      textBox11.addNewTextParagraph().addNewTextRun().setText("性别");

      // 创建文本框
      XSLFTextBox textBox2 = slide.createTextBox();
      // x y设置距离w h 设置大小
      textBox2.setAnchor(new Rectangle2D.Double(30,100, 600, 50));
      // 设置文本框的内容
      textBox2.addNewTextParagraph().addNewTextRun().setText("时间");
      // 创建文本框
      XSLFTextBox textBox22 = slide.createTextBox();
      // x y设置距离w h 设置大小
      textBox22.setAnchor(new Rectangle2D.Double(250,100, 600, 50));
      // 设置文本框的内容
      textBox22.addNewTextParagraph().addNewTextRun().setText("地点");

      // 创建文本框
      XSLFTextBox textBox3 = slide.createTextBox();
      // x y设置距离w h 设置大小
      textBox3.setAnchor(new Rectangle2D.Double(30,150, 600, 50));
      // 设置文本框的内容
      textBox3.addNewTextParagraph().addNewTextRun().setText("事件"
      // 创建文本框
      XSLFTextBox textBox33 = slide.createTextBox();
      // x y设置距离w h 设置大小
      textBox33.setAnchor(new Rectangle2D.Double(250,150, 600, 50));
      // 设置文本框的内容
      textBox33.addNewTextParagraph().addNewTextRun().setText("备注");


      // 插入图片
      // 获取图片的file对象
      File file = new File("C:\\图片.png");
      // 获取字节流
      byte[] bt = FileUtils.readFileToByteArray(file);
      XSLFPictureData idx = ppt.addPicture(bt, PictureData.PictureType.PNG);
      // 插入图片
      XSLFPictureShape pic = slide.createPicture(idx);
      pic.setAnchor(new Rectangle2D.Double(30,200,350,150));


      // 写入ppt中
      ppt.write(new FileOutputStream("输出PPT"+".pptx"));
    }

2.模板处理
import com.oppo.ipd.plm.mechanical.web.structure.PPTExport.bean.WeekAnalyseModel;
import org.apache.commons.io.FileUtils;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.*;
import org.apache.poi.xslf.usermodel.XSLFTextRun;
import org.apache.poi.xslf.usermodel.XSLFTextShape;

import java.awt.*;
import java.io.*;
import java.net.URL;
import java.util.Iterator;

/**
* <p>PowerPoint文件工具基类
* <p>
* <p>通用的PowerPoint文件工具基类,可用于从PowerPoint文档中抽取文本信息
*/
public class BasePowerPointFileUtil {



    /**
   * 渲染、绘制文本框
   *
   * @param shape
   * @param data
   */
    public static void renderShapeAndPicture(Shape shape, WeekAnalyseModel data, String rankType) {
      //判断是否是文本框
      if (shape instanceof TextShape) {
            BasePowerPointFileUtil.replace(shape, data,rankType);
      } else if (shape instanceof GroupShape) {
            Iterator groupShapes = ((GroupShape) shape).iterator();
            while (groupShapes.hasNext()) {
                Shape groupShape = (Shape) groupShapes.next();
                BasePowerPointFileUtil.renderShapeAndPicture(groupShape, data,rankType);
            }
      } else if (shape instanceof TableShape) {
            TableShape tableShape = ((TableShape) shape);
            int column = tableShape.getNumberOfColumns();
            int row = tableShape.getNumberOfRows();
            for (int r = 0; r < row; r++) {
                for (int c = 0; c < column; c++) {
                  BasePowerPointFileUtil.replace(tableShape.getCell(r, c), data,rankType);
                }
            }
      } else if (shape instanceof PictureShape) {
            //判断是否是图片框
            PictureShape pictureShape = (PictureShape) shape;
            PictureData pictureData = pictureShape.getPictureData();
            byte[] bytes = BufferStreamForByte(URLToFile(data.getPictureURL()), 1024);
            try {
                pictureData.setData(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
      }

    }


    /**
   * 替换模板PPT中的值
   *
   * @param shape
   * @param weekAnalyseModel
   */
    public static void replace(Shape shape, WeekAnalyseModel weekAnalyseModel,String rankType) {
      //List<WeekAnalyseModel>是我们项目自己定义的model,可改成其他业务的model
      if (shape instanceof TextShape) {

            String replaceText = ((XSLFTextShape) shape).getText();
            XSLFTextRun xslfTextRun = null;
            //替换数据的业务逻辑,待优化
            switch (replaceText) {
                case "{name}":
                  xslfTextRun = ((XSLFTextShape) shape).setText(weekAnalyseModel.getName());
                  break;
                case "{person}":
                  xslfTextRun = ((XSLFTextShape) shape).setText(weekAnalyseModel.getPerson());
                  break;

            }

            //空值过滤,设置样式
            if (xslfTextRun != null) {
                if (rankType.equals("未定义")||rankType.equals("未定义")){
                  setTextStyle(xslfTextRun);
                }else if (rankType.equals("未定义")||rankType.equals("未定义")){
                  setTextStyleCertificate(xslfTextRun);
                }
            }
      }
    }

    /**
   * 设置字体样式
   *
   * @param xslfTextRun
   */
    private static void setTextStyle(XSLFTextRun xslfTextRun) {
      xslfTextRun.setFontFamily("等线(正文)");
      Color color = new Color(255, 255, 255);
      xslfTextRun.setFontColor(color);
      xslfTextRun.setFontSize(40.0);
      xslfTextRun.setBold(true);
    }

    /**
   * 设置证书字体样式
   *
   * @param xslfTextRun
   */
    private static void setTextStyleCertificate(XSLFTextRun xslfTextRun) {
      xslfTextRun.setFontFamily("宋体");
      Color color = new Color(0, 0, 0);
      xslfTextRun.setFontColor(color);
      xslfTextRun.setFontSize(32.0);
      xslfTextRun.setBold(true);
    }

    /**
   * 将文件转为字节数组
   * @param file
   * @param size
   * @return
   */
    public static byte[] BufferStreamForByte(File file, int size) {
      byte[] content = null;
      try {
            BufferedInputStream bis = null;
            ByteArrayOutputStream out = null;
            try {
                FileInputStream input = new FileInputStream(file);
                bis = new BufferedInputStream(input, size);
                byte[] bytes = new byte;
                int len;
                out = new ByteArrayOutputStream();
                while ((len = bis.read(bytes)) > 0) {
                  out.write(bytes, 0, len);
                }

                bis.close();
                content = out.toByteArray();
            } finally {
                if (bis != null) {
                  bis.close();
                }
                if (out != null) {
                  out.close();
                }
            }
      } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
      }
      return content;

    }

    /**
   * 读取网络中的图片
   * @param url https://www.kziyue.com/wp-content/uploads/2019/06/5bca-hxyuaph9825616.jpg
   * @return
   */
    public static File URLToFile(String url){
      File file1 = new File("replace.png");
      try {

            URL url1 = new URL(url);
            FileUtils.copyURLToFile(url1,file1);

      } catch (IOException e) {
            e.printStackTrace();
      }
      File absoluteFile = file1.getAbsoluteFile();
      return file1;
    }


}


3.内容实体类
import lombok.Data;

@Data
public class WeekAnalyseModel {

    private String name;
    private String pictureURL;
    private String person;
}

4.测试代码:
   public static void main(String[] args) throws Exception {
      //载入数据
      WeekAnalyseModel weekAnalyseModel=new WeekAnalyseModel();
      weekAnalyseModel.setName("数据来源1");
      weekAnalyseModel.setPerson("数据来源1");
      weekAnalyseModel.setPictureURL("http://dev.itqu.net/1.jpg");


      WeekAnalyseModel weekAnalyseModel2=new WeekAnalyseModel();
      weekAnalyseModel2.setName("数据来源2");
      weekAnalyseModel2.setPerson("数据来源2");
      weekAnalyseModel2.setPictureURL("http://dev.itqu.net/2.jpg");

      WeekAnalyseModel weekAnalyseModel3=new WeekAnalyseModel();
      weekAnalyseModel3.setName("数据来源3");
      weekAnalyseModel3.setPerson("数据来源3");
      weekAnalyseModel3.setPictureURL("http://dev.itqu.net/3.jpg");

      ArrayList arrayList=new ArrayList();
      arrayList.add(weekAnalyseModel);
      arrayList.add(weekAnalyseModel2);
      arrayList.add(weekAnalyseModel3);

      //载入模板ppt,创建模板副本
      InputStream inputStream = new FileInputStream("model.pptx");
      copyFile("model.pptx","model-copy.pptx");
      InputStream inputStreamCopy = new FileInputStream("model-copy.pptx");

      RenderPowerPointTemplate.renderPowerPointTemplateOfCertificate(inputStreamCopy,arrayList,"out");


    }

    private static void copyFile(String source, String copy) {
      Path sourcePath = Paths.get(source);
      Path destinationPath = Paths.get(copy);
      try {
            Files.copy(sourcePath, destinationPath,StandardCopyOption.REPLACE_EXISTING);
      } catch (FileAlreadyExistsException e) {
            // 目标文件已经存在
      } catch (IOException e) {
            // 发生了其他错误
            e.printStackTrace();
      }
    }



MercyBund 发表于 2025-3-9 03:42:48

Как зайти на официальный сайт мостбет и начать делать ставки на спорт, играть в казино и пользоваться другими услугами букмекерской конторы.

MercyBund 发表于 2025-3-10 00:04:55

На сайте представлена возможность скачать бесплатно приложение mostbet для ставок на спорт и казино, обеспечивающее удобный доступ к игровой платформе и актуальным событиям.

MercyBund 发表于 2025-3-16 03:52:23

https://mostbet-wof5.top/ официальную информацию о крупнейшем букмекере Мостбет и его основных преимуществах и возможностях для игроков.

MercyBund 发表于 2025-3-17 14:36:27

Статья о популярных игровых автоматах на сайте мостбет: особенности игры, правила и советы для успешной игры.

MercyBund 发表于 2025-3-18 06:52:19

https://mostbet-wir3.top/ - как скачать приложение Mostbet на андроид и начать делать ставки на спорт в любое время и в любом месте.

MercyBund 发表于 2025-4-1 18:30:48

https://mostbet-weh4.xyz/ - как скачать зеркало Mostbet для быстрого доступа к популярным играм и ставкам на спорт без блокировок.

MercyBund 发表于 2025-4-9 15:10:40

https://mostbet-wed1.top/ о возможности получения бездепозитных бонусов от букмекерской конторы Мостбет и какие условия необходимо выполнить для их активации.

Edithpab 发表于 2025-4-10 19:45:48

Ladbrokes online casino review l82oyb

MercyBund ??? 2025-3-10 00:04
На сайте представлена возможность скачать бесплатно п ...

You explained this really well!
Free online casino coupons http://ascrew.awardspace.info/index.php?PHPSESSID=9b88756c6204924735a5e3f296d79692&topic=10793.0white label online casino cost.
Real casinos online http://web068.dmonster.kr/bbs/board.php?bo_table=qa&wr_id=24219stake online casino location.
Top 20 online casinos https://www.yic.co.kr/bbs/board.php?bo_table=free&wr_id=673897online casino games michigan.
Online casino welcome bonus 100 https://pattern-wiki.win/wiki/How_To_Sell_Casino_Onlinefree spins online casinos.
Vegas casino online ndb http://www.daongil.com/bbs/board.php?bo_table=free&wr_id=691795raja online casino!

https://skepticseekers.com/mybb/showthread.php?tid=41458
https://bbs.sinbadgroup.org/index.php?xjkh-tampa-s-poster-pup-for-new-cancer-treatment.t48661.html/page-6394#post-275373
https://forum.game-kosmos.org/index.php?threads/yyy-online-casino-x25cer.17759/
https://www.plik.cn/index.php?topic=165736.new#new
http://demo.qkseo.in/viewtopic.php?pid=1679515#p1679515

takbivaet 发表于 2025-4-13 06:02:18

<a href="kra29cc.icu">обмен биткоинов на меге</a>
页: [1] 2 3
查看完整版本: PPT导出-模板和自定义处理方案