Springboot生成Word/EXECL/PPTX文档

news2024/10/5 18:32:44

目录

一、概述 

二、使用介绍 

第一种Poi-tl:

1、介绍 

2、功能

第二种Poi:

什么是POI

二进制分布

源码分发


一、概述 

Word模板引擎:使用Word模板和数据生成对应的Word文档。

方案移植性功能性易用性

Poi-tl

Java跨平台

Word模板引擎,基于Apache POI,提供更友好的API

低代码,准备文档模板和数据即可

Apache POI

Java跨平台

Apache项目,封装了常见的文档操作,也可以操作底层XML结构

文档不全,这里有一个教程:Apache POI Word快速入门

Freemarker

XML跨平台

仅支持文本,很大的局限性

不推荐,XML结构的代码几乎无法维护

OpenOffice

部署OpenOffice,移植性较差

-

需要了解OpenOffice的API

HTML浏览器导出

依赖浏览器的实现,移植性较差

HTML不能很好的兼容Word的格式,样式糟糕

-

Jacob、winlib

Windows平台

-

复杂,完全不推荐使用

使用场景:

               1.合同导出 2.题库导出 等等

二、使用介绍 

第一种Poi-tl:

1、介绍 

        poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让人喜悦的特性。

poi-tl supports custom functions (plug-ins), functions can be executed anywhere in the Word template, do anything anywhere in the document is the goal of poi-tl.

2、功能

Poi-tl的TDO模式

TDO模式:Template + data-model = output

<dependency>
  <groupId>com.deepoove</groupId>
  <artifactId>poi-tl</artifactId>
  <version>1.12.0</version>
</dependency>
XWPFTemplate template = XWPFTemplate.compile("template.docx").render(
  new HashMap<String, Object>(){{
    put("title", "Hi, poi-tl Word模板引擎");
}});  
template.writeAndClose(new FileOutputStream("output.docx"));
compile 编译模板 - Template
render 渲染数据 - data-model
write 输出到流 - output

Template:模板

        模板是Docx格式的Word文档,你可以使用Microsoft office、WPS Office、Pages等任何你喜欢的软件制作模板,也可以使用Apache POI代码来生成模板。

        所有的标签都是以{{开头,以}}结尾,标签可以出现在任何位置,包括页眉,页脚,表格内部,文本框等,表格布局可以设计出很多优秀专业的文档,推荐使用表格布局。

        poi-tl模板遵循所见即所得的设计,模板和标签的样式会被完全保留。

Data-model:数据

数据类似于哈希或者字典,可以是Map结构(key是标签名称):

Map<String, Object> data = new HashMap<>();
data.put("name", "Sayi");
data.put("start_time", "2019-08-04");

可以是对象(属性名是标签名称):

public class Data {
  private String name;
  private String startTime;
  private Author author;
}
数据可以是树结构,每级之间用点来分隔开,比如{{author.name}}标签对应的数据是author对象的name属性值。

        FreeMarker、Velocity文本模板中可以通过三个标签设置图片路径、宽和高:

<img src="{{path}}" width="{{width}}" height="{{height}}">

        但是Word模板不是由简单的文本表示,所以在渲染图片、表格等元素时提供了数据模型,它们都实现了接口RenderData,比如图片数据模型PictureRenderData包含图片路径、宽、高三个属性。

Output:输出

以流的方式进行输出:

template.write(OutputStream stream);

可以写到任意输出流中,比如文件流:

template.write(new FileOutputStream("output.docx"));

比如网络流:

response.setContentType("application/octet-stream");
response.setHeader("Content-disposition","attachment;filename=\""+"out_template.docx"+"\"");

// HttpServletResponse response
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out); // 最后不要忘记关闭这些流。

插件

        插件,又称为自定义函数,它允许用户在模板标签位置处执行预先定义好的函数。由于插件机制的存在,我们几乎可以在模板的任何位置执行任何操作。

插件是poi-tl的核心,默认的标签和引用标签都是通过插件加载。默认有八个策略插件,用来处理文本、图片、列表、表格、文档嵌套、引用图片、引用多系列图表、引用单系列图表等

  • TextRenderPolicy

  • PictureRenderPolicy

  • NumberingRenderPolicy

  • TableRenderPolicy

  • DocxRenderPolicy

  • MultiSeriesChartTemplateRenderPolicy

  • SingleSeriesChartTemplateRenderPolicy

  • DefaultPictureTemplateRenderPolicy

案例:

/**
     * 生成word 普通格式
     * @param filePath
     * @throws IOException
     */
    public static void generateWordXWPFTemplate(String filePath) throws IOException {
        Map<String, Object> content = new HashMap<>();
        content.put("title", "Springboot 生成Word文档");
        content.put("author", "zhw");
        content.put("site", new HyperlinkTextRenderData("http://deepoove.com/poi-tl/", "http://deepoove.com/poi-tl/"));

        content.put("poiText",
            "poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让人喜悦的特性。");

        content.put("poiTextTwo", "条形图(3D条形图)、柱形图(3D柱形图)、面积图(3D面积图)、折线图(3D折线图)、雷达图、饼图(3D饼图)、散点图等图表渲染");
        content.put("poiTlList", Numberings.create("将标签渲染为文本", "将标签渲染为表格","将标签渲染为列表"));

        RowRenderData headRow = Rows.of("标题一", "标题二", "标题三", "标题四", "标题五").textColor("FFFFFF").bgColor("4472C4").center().create();
        TableRenderData table = Tables.create(headRow);

        List<Integer> dataList=new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            dataList.add(i);
        }
        List<List<Integer>> subList = Lists.partition(dataList, 5);
        for (List<Integer> list : subList) {
            for (Integer value : list) {
                table.addRow(Rows.create(value+"", value+"", value+"", value + "", value+""));
            }

        }
        //填充数据
        content.put("poiTable", table);

        //图片
        Resource resource = new ClassPathResource("a.jpeg");
        content.put("poiImage", Pictures.ofStream(new FileInputStream(resource.getFile())).create());

        //读取模板
        XWPFTemplate render = XWPFTemplate.compile(new ClassPathResource("poi-tl-template.docx").getFile()).render(content);
        //渲染模板
        render.write(new FileOutputStream(filePath));
    }

    /**
     * 导出markdown为word
     *
     * @param filePath
     * @throws IOException
     */
    public static void generateWordXWPFTemplateMD(String filePath) throws IOException {
        MarkdownRenderData code = new MarkdownRenderData();

        Resource resource = new ClassPathResource("test.md");
        code.setMarkdown(new String(Files.readAllBytes(resource.getFile().toPath())));
        code.setStyle(MarkdownStyle.newStyle());

        Map<String, Object> data = new HashMap<>();
        data.put("md", code);

        Configure config = Configure.builder().bind("md", new MarkdownRenderPolicy()).build();
        XWPFTemplate render = XWPFTemplate.compile(new ClassPathResource("markdown_template.docx").getFile(), config).render(data);
        render.write(new FileOutputStream(filePath));
    }

第二种Poi:

        Apache POI 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。更多请参考[官方文档](https://poi.apache.org/index.html)。

什么是POI

Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”.

        Apache POI 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。更多请参考官方文档。

 POI 即可以导出word文档也可以到出Execl 和PPTX文档。

二进制分布

  • poi-bin-5.2.3-20220909.tgz (58 MB,签名(.asc),校验和:SHA-256, SHA-512)
  • poi-bin-5.2.3-20220909.zip (58 MB,签名 (.asc),校验和:SHA-256、 SHA-512)

源码分发

  • poi-src-5.2.3-20220909.tgz (112 MB,签名(.asc),校验和:SHA-256, SHA-512)
  • poi-src-5.2.3-20220909.zip (116 MB,签名(.asc),校验和:SHA-256, SHA-512) 
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.2</version>
        </dependency>
  • HSSF - 提供读写 Microsoft Excel XLS 格式 (Microsoft Excel 97 (-2003)) 档案的功能。

  • XSSF - 提供读写 Microsoft Excel OOXML XLSX 格式 (Microsoft Excel XML (2007+)) 档案的功能。

  • SXSSF - 提供低内存占用量读写 Microsoft Excel OOXML XLSX 格式档案的功能。

  • HWPF - 提供读写 Microsoft Word DOC97 格式 (Microsoft Word 97 (-2003)) 档案的功能。

  • XWPF - 提供读写 Microsoft Word DOC2003 格式 (WordprocessingML (2007+)) 档案的功能。

  • HSLF/XSLF - 提供读写 Microsoft PowerPoint 格式档案的功能。

  • HDGF/XDGF - 提供读 Microsoft Visio 格式档案的功能。

  • HPBF - 提供读 Microsoft Publisher 格式档案的功能。

  • HSMF - 提供读 Microsoft Outlook 格式档案的功能。

1、Word文件

1.构建文档对象

XWPFDocument doc = new XWPFDocument();

2.创建段落

XWPFParagraph xwpfParagraph = doc.createParagraph();
//设置位置 居中 左 右
xwpfParagraph.setAlignment(ParagraphAlignment.CENTER);

3.设置文本

XWPFRun xwpfRun = xwpfParagraph.createRun();
//加粗
xwpfRun.setBold(true);
//文本
xwpfRun.setText(content);
//字体大小
xwpfRun.setFontSize(fontSize);

4.设置表格

// 表格
XWPFParagraph paragraph = doc.createParagraph();
//创建table 表格 5行 5 列
XWPFTable table = paragraph.getDocument().createTable(5, 5);
//设置宽度
table.setWidth(500);
//设置每行 内外边距
table.setCellMargins(40, 40, 40, 40);

// 表格属性
CTTblPr tablePr = table.getCTTbl().addNewTblPr();
// 表格宽度
CTTblWidth width = tablePr.addNewTblW();
width.setW(BigInteger.valueOf(8000));

//设置标题
List<XWPFTableCell> tableCells = table.getRow(0).getTableCells();
tableCells.get(0).setText("标题一");
tableCells.get(1).setText("标题二");
tableCells.get(2).setText("标题三");
tableCells.get(3).setText("标题四");
tableCells.get(4).setText("标题五");

//填充数据
for (int i = 1; i < 5; i++) {
    tableCells = table.getRow(i).getTableCells();
    for (int j = 0; j < 5; j++) {
        tableCells.get(j).setText("a"+j);
    }
}

5.设置图片

// 图片
InputStream stream = null;
try {
    XWPFParagraph paragraph2 = doc.createParagraph();
    Resource resource = new ClassPathResource("a.jpeg");
    stream = new FileInputStream(resource.getFile());
    XWPFRun run = paragraph2.createRun();
    //填充图片对象 设置 宽高
    run.addPicture(stream, Document.PICTURE_TYPE_PNG, "Generated", Units.toEMU(256), Units.toEMU(256));
} catch (Exception e) {
    e.printStackTrace();
}

实现案例

package com.lean.word;

import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

/**
 *https://poi.apache.org/index.html
 */
public class WordPoiTest {

    public static void main(String[] args) throws Exception {

        XWPFDocument xwpfDocument = generateWordXWPFDocument();
        xwpfDocument.write(new FileOutputStream("./doc/aa.docx"));
    }

    public static XWPFDocument generateWordXWPFDocument() {
        //1.构建文档对象
        XWPFDocument doc = new XWPFDocument();

        // 标题
        XWPFParagraph xwpfParagraph = doc.createParagraph();
        xwpfParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun xwpfRun = xwpfParagraph.createRun();
        xwpfRun.setBold(true);
        xwpfRun.setFontFamily("宋体");
        xwpfRun.setText("Springboot 生成Word文档");
        xwpfRun.setFontSize(22);

        // 段落
        createChapter(doc, "1. 概述",18);
        createChapter(doc, "1.1 介绍POI",12);
        createParagraph(doc,
            "Apache POI 项目的任务是创建和维护 Java API,以便根据 Office Open XML 标准 (OOXML) 和 Microsoft 的 OLE 2 复合文档格式 (OLE2) 处理各种文件格式。简而言之,您可以使用 Java 读写 MS Excel 文件。此外,您还可以使用 Java 读写 MS Word 和 MS PowerPoint 文件。Apache POI 是您的 Java Excel 解决方案(适用于 Excel 97-2008)。我们有完整的 API 用于移植其他 OOXML 和 OLE2 格式,欢迎其他人参与。");
        createChapter(doc, "1.2 二进制分布",12);
        createParagraph(doc, "poi-bin-5.2.3-20220909.tgz (58 MB,签名(.asc),校验和:SHA-256, SHA-512)");
        createParagraph(doc, "poi-bin-5.2.3-20220909.zip (58 MB,签名 (.asc),校验和:SHA-256、 SHA-512)");

        // Chapter 2
        createChapter(doc, "2. 实现案例",18);
        createChapter(doc, "2.1 表单展示",12);
        createParagraph(doc, "假数据为例");

        // 表格
        XWPFParagraph paragraph = doc.createParagraph();
        //创建table 表格 5行 5 列
        XWPFTable table = paragraph.getDocument().createTable(5, 5);
        //设置宽度
        table.setWidth(500);
        //设置每行 内外边距
        table.setCellMargins(40, 40, 40, 40);

        // 表格属性
        CTTblPr tablePr = table.getCTTbl().addNewTblPr();
        // 表格宽度
        CTTblWidth width = tablePr.addNewTblW();
        width.setW(BigInteger.valueOf(8000));

        //设置标题
        List<XWPFTableCell> tableCells = table.getRow(0).getTableCells();
        tableCells.get(0).setText("标题一");
        tableCells.get(1).setText("标题二");
        tableCells.get(2).setText("标题三");
        tableCells.get(3).setText("标题四");
        tableCells.get(4).setText("标题五");

        //填充数据
        for (int i = 1; i < 5; i++) {
            tableCells = table.getRow(i).getTableCells();
            for (int j = 0; j < 5; j++) {
                tableCells.get(j).setText("a"+j);
            }
        }

        createChapter(doc, "2.2 图片展示",12);
        createParagraph(doc, "以导出图片为例");
        // 图片
        InputStream stream = null;
        try {
            XWPFParagraph paragraph2 = doc.createParagraph();
            Resource resource = new ClassPathResource("a.jpeg");
            stream = new FileInputStream(resource.getFile());
            XWPFRun run = paragraph2.createRun();
            //填充图片对象 设置 宽高
            run.addPicture(stream, Document.PICTURE_TYPE_PNG, "Generated", Units.toEMU(256), Units.toEMU(256));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return doc;
    }


    public static void createChapter(XWPFDocument doc, String content,Integer fontSize) {
        XWPFParagraph xwpfParagraph = doc.createParagraph();
        //设置位置 居中 左 右
        xwpfParagraph.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun xwpfRun = xwpfParagraph.createRun();
        //加粗
        xwpfRun.setBold(true);
        //文本
        xwpfRun.setText(content);
        //字体大小
        xwpfRun.setFontSize(fontSize);
    }


    public static void createParagraph(XWPFDocument doc, String content) {
        XWPFParagraph xwpfParagraph = doc.createParagraph();
        XWPFRun xwpfRun = xwpfParagraph.createRun();
        xwpfRun.setText(content);
        xwpfRun.setFontSize(11);
    }
}

2、PPT文件

基础类:

XMLSlideShow:创建和管理演示文稿

方法描述
addPicture

添加图片。

XSLFSlide createSlide() 

创建空白幻灯片。

XSLFSlide createSlide(XSLFSlideLayout布局) 

创建具有给定幻灯片布局的幻灯片。

List< XSLFPictureData> getAllPictures()

返回所有图片的数组。

Dimension getPageSize()

 当前页面大小。

XSLFSlideMaster [] getSlideMasters()

 返回所有幻灯片的数组。

XSLFSlide [] getSlides()

 返回所有幻灯片。

XslFSlide removeSlide(int index)

 删除幻灯片。

void setPageSize(java.awt.Dimension pgSize)

 重置页面大小。

void setSlideOrder(XSLFSlide slide,int newIndex)

 重新排序幻灯片。

XSLFSlide:创建和管理幻灯片

方法描述
XSLFBackground getBackground()

用于检索幻灯片背景的颜色和锚点等详细信息。

XSLFSlideLayout getSlideLayout()

提供对当前幻灯片的 XSLFSlideLayout 对象的访问。

XSLFSlideMaster getSlideMaster()

提供对当前幻灯片的幻灯片母版的访问。

XSLFTheme getTheme()

返回当前幻灯片的 XSLFTheme 对象。

java.lang.String getTitle()

返回当前幻灯片的标题。

XSLFSlide importContent(XSLFSheet src)

将另一张幻灯片的内容复制到此幻灯片。

createPicture()创建图片管理对象
createTextBox()获取文本框对象
addChart(XSLFChart chart)插入图形界面如折线图、柱状图等
createTable()获取操作表单对象

XSLFSlideMaster:幻灯片母版

方法描述
XSLFBackground getBackground()

返回幻灯片母版的常用背景。

XSLFSlideLayout getLayout(SlideLayout type)

返回XSLFSlideLayout对象。

XSLFSlideLayout [] getSlideLayouts()

返回此幻灯片母版中的所有幻灯片布局。

XSLFSlideLayout: 幻灯片布局

方法描述
void copyLayout(XSLFSlide幻灯片)

将占位符从此布局复制到给定幻灯片。

 XSLFTextBox: 文本框

方法描述
XSLFSlide 类方法:createTextBox()

获取文本框

XSLFTextParagraph: 文本段落

方法描述
XSLFTextRun addLineBreak()

在段落中插入换行符。

XSLFTextRun addNewTextRun()

在段落中添加新的文本行。

setBulletAutoNumber(ListAutoNumber scheme,int startAt)

将自动编号的项目符号点应用于段落。

void setIndent(double value)

将缩进设置为段落中的文本。

void setLeftMargin(double value)

用于添加段落的左边距。

void setLineSpacing(double line spacing)

此方法用于在段落中设置行间距。

void setTextAlign(TextAlign align)

用于设置要设置为段落的对齐方式。

XSLFTextParagraph : 文本运行,用 XSLFTextRun 类来管理段落的文本运行。

方法描述
addNewTextRun()获取XSLFTextRun类来管理文本
XSLFHyperlink createHyperlink()

创建超链接。

XSLFHyperlink getHyperlink()

用于获取超链接。

java.lang.String getText()

以Java字符串形式返回此Text节点的值。

void setBold(boolean bold)

用于以粗体设置文本。

void setCharacterSpacing(double spc)

设置文本运行中的字符之间的间距。

void setFontColor(java.awt.Color color)

设置文本的字体颜色。

void setFontSize(double fontSize)

设置文本的字体大小。

void setItalic(boolean italic)

用于使段落斜体。

void setStrikethrough(boolean strike)

用于将一段文本格式化为删除线文本。

void setSubscript(boolean flag)

用于将文本格式化为下标。

void setSuperscript(boolean flag)

用于将此运行中的文本格式化为上标。

void setText(java.lang.String text)

用于在运行中设置文本。

void setUnderline(Boolean underline)

用于在文本运行中对文本加下划线。

XSLFTextShape: 文本形状

方法描述
void setPlaceholder(Placeholder placeholder)

使用此方法,可以选择占位符。

Placeholder getTextType()

返回当前占位符的类型。

void clearText()

清除当前文本形状的文本区域。

XSLFTextParagraph addNewTextParagraph()

向形状添加新的段落运行。

void drawContent(java.awt.Graphics2D graphics)

绘制任何内容。

XSLFHyperlink :超链接

方法描述
java.net.URI getTargetURL()

返回演示文稿幻灯片中存在的网址。

void setAddress(java.lang.String address)

用于将地址设置为URL。

void setAddress(XSLFSlide幻灯片)

将地址设置为演示文稿幻灯片中显示的网址。

        创建PPT之前需要先创建一个空白的ppt,然后在其上面填充对应的文本,表格,图片等信息。且填充的时候需要定位,放置在固定的位置上。

// x y设置距离  w h 设置大小

setAnchor(new Rectangle2D.Double(300, 50, 100, 50));

生成PPT有两种方式:

1、代码生成PPT,需要编写大量的逻辑代码,比较复杂,尤其生成:折线图,柱状图等图形。

2、通过PPT模板生成,操作简单,使用方便。

读取PPT:

​
/**
     * 读取ppt
     */
    public static void readPpt(String filePath) {
        File file = new File(filePath);
        StringBuffer content = new StringBuffer();
        try {
            InputStream is = new FileInputStream(file);
            XMLSlideShow xmlSlideShow = new XMLSlideShow(is);
            // 获取ppt中所有幻灯片
            List<XSLFSlide> slides = xmlSlideShow.getSlides();
            for (XSLFSlide slide : slides) {
                List<XSLFShape> shapes = slide.getShapes();
                for (XSLFShape shape : shapes) {
                    System.out.println(shape.getShapeName());
                }
            }
            // 获取所有的图表
            List<XSLFChart> charts = xmlSlideShow.getCharts();
            for (XSLFChart chart : charts) {
                // 获取图表标题
                String text = chart.getTitleShape().getText();
                System.out.println(text);
            }
            xmlSlideShow.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(content.toString());
    }

​

ppt 转成图片: 

/**
     * ppt 转成图片
     * @param filePath
     * @param times 生成图片放大的倍数,倍数越高,清晰度越高
     * @throws Exception
     */
    public static void pptToPng(String filePath,Integer times) throws Exception {
        File file = new File(filePath);
        XMLSlideShow ppt = new XMLSlideShow(new FileInputStream(file));

        Dimension pgsize = ppt.getPageSize();
        List<XSLFSlide> slideList = ppt.getSlides();
        for (XSLFSlide xslfShapes : slideList) {
            // 解决乱码问题
            XSLFShape[] shapes = xslfShapes.getShapes().toArray(new XSLFShape[0]);
            for (XSLFShape shape : shapes) {
                if (shape instanceof XSLFTextShape) {
                    XSLFTextShape sh = (XSLFTextShape) shape;
                    List<XSLFTextParagraph> textParagraphs = sh.getTextParagraphs();
                    for (XSLFTextParagraph xslfTextParagraph : textParagraphs) {
                        List<XSLFTextRun> textRuns = xslfTextParagraph.getTextRuns();
                        for (XSLFTextRun xslfTextRun : textRuns) {
                            xslfTextRun.setFontFamily("宋体");
                        }
                    }
                }
            }
            // 创建BufferedImage对象,图像的尺寸为原来的每页的尺寸*倍数times
            BufferedImage img = new BufferedImage(pgsize.width * times,
                    pgsize.height * times, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics = img.createGraphics();
            graphics.setPaint(Color.white);
            graphics.scale(times, times);// 将图片放大times倍
            graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width,pgsize.height));
            // 最核心的代码
            xslfShapes.draw(graphics);
            // 这里设置图片的存放路径和图片的格式(jpeg,png,bmp等等),注意生成文件路径
            FileOutputStream out = new FileOutputStream("./doc/ppt_image_" + System.currentTimeMillis() + ".png");
            // 写入到图片中去
            ImageIO.write(img, "png", out);
            out.close();
        }
        System.out.println("Image successfully created");
    }

合并 pdf :

/**
     * 合并 pdf
     *
     * @param files
     * @param outPaths
     * @throws Exception
     */
    public static void mergePptx(String[] files, String outPaths) throws Exception {
        XMLSlideShow ppt = new XMLSlideShow();
        for (String arg : files) {
            FileInputStream fileInputStream = new FileInputStream(arg);
            XMLSlideShow src = new XMLSlideShow(fileInputStream);
            for (XSLFSlide srcSlide : src.getSlides()) {
                ppt.createSlide().importContent(srcSlide);
            }
        }
        FileOutputStream out = new FileOutputStream(outPaths);
        ppt.write(out);
        System.out.println("Merging done successfully");
        out.close();
    }

生成PPT 

第一种:

public static void createBaseXSLFPPT() throws Exception {
        // 创建一个新的空幻灯片
        XMLSlideShow ppt = new XMLSlideShow();
        // 检索页面大小。坐标以点表示 (72 dpi)
        // Dimension pgsize = ppt.getPageSize();
        // int pgx = pgsize.width; //以磅为单位的滑动宽度
        // System.out.println(pgx);
        // int pgy = pgsize.height; //以磅为单位的滑动高度
        // System.out.println(pgy);
        // //设置新页面大小
        // ppt.setPageSize(new java.awt.Dimension(1024, 768));

        // 空白幻灯片 设置标题
        XSLFSlide titleslide = ppt.createSlide();
        XSLFTextShape titleShape = titleslide.createTextBox();
        titleShape.setPlaceholder(Placeholder.TITLE);
        titleShape.setText("This is a slide title");
        titleShape.setAnchor(new Rectangle(50, 50, 400, 100));

        // 获取布局模板 默认 BLANK布局
        XSLFSlideMaster defaultMaster = ppt.getSlideMasters().get(0);
        // 标题幻灯片布局
        XSLFSlideLayout titleLayout = defaultMaster.getLayout(SlideLayout.TITLE);
        // 添加第一张幻灯片
        XSLFSlide firstSlide = ppt.createSlide(titleLayout);
        // 添加标题
        XSLFTextShape title = firstSlide.getPlaceholder(0);
        title.setText("标题");

        XSLFTextBox shape1 = firstSlide.createTextBox();
        // initial height of the text box is 100 pt but
        Rectangle anchor = new Rectangle(10, 100, 300, 100);
        shape1.setAnchor(anchor);

        XSLFTextParagraph p1 = shape1.addNewTextParagraph();
        XSLFTextRun textRun = p1.addNewTextRun();
        textRun.setText("org.apache.poi.xslf.usermodel.XSLFTextParagraph");
        textRun.setFontSize(24d);
        textRun.setFontColor(new Color(85, 142, 213));

        XSLFTextParagraph p2 = shape1.addNewTextParagraph();

        p2.setSpaceBefore(-20d);
        p2.setSpaceAfter(300d);
        XSLFTextRun textRun1 = p2.addNewTextRun();
        textRun1.setText("com/lean/word/PptTest.java:157");
        textRun1.setFontSize(16d);

        XSLFTextParagraph p3 = shape1.addNewTextParagraph();

        XSLFTextRun textRun2 = p3.addNewTextRun();
        textRun2.setText("com/lean/word/PptTest.java:163");
        textRun2.setFontSize(24d);
        textRun2.setFontColor(new Color(85, 142, 213));

        XSLFTextParagraph p4 = shape1.addNewTextParagraph();
        // 设置距离之前的间隔
        p4.setSpaceBefore(-20d);
        // 设置距离之后的间隔
        p4.setSpaceAfter(300d);
        XSLFTextRun textRun3 = p4.addNewTextRun();
        // 字体大小
        textRun3.setFontSize(16d);
        textRun3.setText("V2.returns.get_return_list API: 可获取一个店铺的退货退款申请列表," + "每个申请都将会返回一个return_sn作为唯一标识,买家针对同一个订单可能会提交多个return_sn。"
            + "返回参数中包含order_sn即为此退货退款申请关联的订单号。另外,接口支持筛选不同类型的退货退款申请,包括退货状态(status)、"
            + "谈判状态(negotiation_status)、证据上传状态(seller_proof_status)、卖家赔偿状态(seller_compensation_status)。");
        // 调整形状大小以适合文本
        shape1.resizeToFitText();

        // 标题和内容 第三个布局
        XSLFSlideLayout titleBodyLayout = defaultMaster.getLayout(SlideLayout.TITLE_AND_CONTENT);
        XSLFSlide slide2 = ppt.createSlide(titleBodyLayout);
        XSLFTextShape title2 = slide2.getPlaceholder(0);
        title2.setText("第二个标题");
        XSLFTextShape body2 = slide2.getPlaceholder(1);
        body2.clearText(); // 取消设置任何现有的文本
        body2.addNewTextParagraph().addNewTextRun().setText("第一段");
        body2.addNewTextParagraph().addNewTextRun().setText("第二段");
        body2.addNewTextParagraph().addNewTextRun().setText("第三段");

        // 设置层级
        XSLFTextParagraph xslfTextRuns1 = body2.addNewTextParagraph();
        xslfTextRuns1.setIndentLevel(0);
        xslfTextRuns1.addNewTextRun().setText("第一段");
        XSLFTextParagraph xslfTextRuns2 = body2.addNewTextParagraph();
        xslfTextRuns1.setIndentLevel(1);
        xslfTextRuns2.addNewTextRun().setText("第二段");
        XSLFTextParagraph xslfTextRuns3 = body2.addNewTextParagraph();
        xslfTextRuns3.setIndentLevel(3);
        xslfTextRuns3.addNewTextRun().setText("第三段");

        // 布局页面
        XSLFSlide slide3 = ppt.createSlide();
        // 构建一个文本框
        XSLFTextBox shape = slide3.createTextBox();
        // 设置文本
        shape.setText("com/lean/word/PptTest.java:210");
        shape.setAnchor(new Rectangle2D.Double(100, 100, 500, 350));

        XSLFTextParagraph p = shape.addNewTextParagraph();
        XSLFTextRun r1 = p.addNewTextRun();
        r1.setText("blue ");
        r1.setFontColor(Color.blue);
        r1.setFontSize(24.);
        XSLFTextRun r2 = p.addNewTextRun();
        r2.setText(" red");
        r2.setFontColor(Color.red);
        r2.setBold(true);
        XSLFTextRun r3 = p.addNewTextRun();
        r3.setFontColor(Color.black);
        r3.setText(" black");
        r3.setFontSize(12.);
        r3.setItalic(true);
        r3.setStrikethrough(true);
        XSLFTextRun r4 = p.addNewTextRun();
        r4.setFontColor(Color.yellow);
        r4.setText(" yellow");
        r4.setUnderlined(true);
        // 创建超链接
        XSLFTextRun r5 = p.addNewTextRun();
        r5.setText("超链接");
        XSLFHyperlink link = r5.createHyperlink();
        link.setAddress("https://poi.apache.org");
        r5.setText("https://poi.apache.org"); // visible text

        // 创建文本框
        XSLFTextBox shape2 = slide3.createTextBox();
        // 定位
        shape2.setAnchor(new Rectangle(300, 50, 200, 50));
        XSLFTextRun textRun4 = shape2.addNewTextParagraph().addNewTextRun();
        XSLFHyperlink link2 = textRun4.createHyperlink();
        textRun4.setText("Go to top");
        // 超链接定位到第三个幻灯片
        link2.linkToSlide(slide2);

        // 创建第四个幻灯片 表格
        XSLFSlide slide4 = ppt.createSlide();
        // 将图像添加到幻灯片
        byte[] pictureData = IOUtils.toByteArray(new FileInputStream("./doc/3.png"));
        XSLFPictureData idx = ppt.addPicture(pictureData, PictureData.PictureType.PNG);
        // 插入图片
        XSLFPictureShape pic = slide4.createPicture(idx);
        pic.setAnchor(new Rectangle2D.Double(100, 100, 500, 350));

        // 插入表格
        createTextList(ppt);

        // 插入表格
        createTable(ppt);

        // 插入表格
        createTableOne(ppt);

        String chartTitle = "10 languages with most speakers as first language";
        String[] seriesdata = new String[] {"countries", "speakers", "language"};

        String[] categories = new String[] {"???????", "?????", "中文", "English", "??????", "日本語", "português", "??????", "Русский язык", "espa?ol"};
        Double[] values1 = new Double[] {58.0, 4.0, 38.0, 118.0, 4.0, 2.0, 15.0, 6.0, 18.0, 31.0};
        Double[] values2 = new Double[] {315.0, 243.0, 1299.0, 378.0, 260.0, 128.0, 223.0, 119.0, 154.0, 442.0};

        /**
         * 柱状图
         */
        createSlideWithChart(ppt, chartTitle, seriesdata, categories, values1, values2);
        /**
         * 扇形图
         */
        createSlideWithChartOne(ppt, chartTitle, seriesdata, categories, values2, COLUMN_SPEAKERS);

        // 柱状图
        createSlideWithChartTwo(ppt);

        // 输出ppt文件
        ppt.write(new FileOutputStream("./doc/2.pptx"));

        //
        readPpt("./doc/2.pptx");

    }

private static void createSlideWithChartTwo(XMLSlideShow ppt) {
        // 创建了一个幻灯片 这就是个空白的幻灯片
        XSLFSlide slide6 = ppt.createSlide();
        // 创建一个图表
        XSLFChart chart = ppt.createChart();
        // 创建一个工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 写入数据
        XSSFSheet sheet = workbook.createSheet();
        XSSFRow row0 = sheet.createRow(0);
        row0.createCell(1).setCellValue("A");
        row0.createCell(2).setCellValue("B");
        for (int i = 0; i < 4; i++) {
            // 设置每一行的字段标题和数据
            XSSFRow row = sheet.createRow(i + 1);
            row.createCell(0).setCellValue((i + 1) + "队");
            row.createCell(1).setCellValue(3);
            row.createCell(2).setCellValue(4);
        }
        // 把工作簿放到图表里,这样可以方便文件更新
        chart.setWorkbook(workbook);
        // 图表头
        chart.setTitleText("测试文本title");
        // 这个是生成图表底部的示例的
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.BOTTOM);
        // x坐标轴 底部
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        // y轴 左侧
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        // 创建图表数据,第一个指定是什么图表 柱状图或者饼图,折线图都ok,
        XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
        // 底部类别的数据源,可以从数组读,也可以从指定一个excel范围
        XDDFCategoryDataSource xddfCategoryDataSource = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(1, 4, 0, 0));
        // 这是第一个柱状图的数据源
        XDDFNumericalDataSource<Double> doubleXDDFNumericalDataSource = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 4, 1, 1));
        // 这是第二个柱状图的数据源
        XDDFNumericalDataSource<Double> doubleXDDFNumericalDataSource2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 4, 2, 2));
        // 把第一组柱状图添加到图表数据里 返回一个系列数据
        XDDFChartData.Series series = data.addSeries(xddfCategoryDataSource, doubleXDDFNumericalDataSource);
        // 第二组
        XDDFChartData.Series series1 = data.addSeries(xddfCategoryDataSource, doubleXDDFNumericalDataSource2);
        // 设置第一个系列的名称 上面那个生成图表底部的示例的就是这里 ,第一个指定名称,第二个可以给一个单元格。两个参数可以有一个为null
        series.setTitle("A", new CellReference(sheet.getRow(0).getCell(1)));
        series1.setTitle("B", new CellReference(sheet.getRow(0).getCell(2)));
        // 数据源转为barchart
        XDDFBarChartData bar = (XDDFBarChartData)data;
        // 这一句是y轴的一个操作,也没懂什么意思,但是没有这个,画的图表会超出画布范围
        leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
        // 是否设置不同的颜色 false就行
        bar.setVaryColors(false);
        // 柱状图的方向
        bar.setBarDirection(BarDirection.COL);
        // 柱状图的类型,不是有什么堆积。。。的
        bar.setBarGrouping(BarGrouping.STANDARD);
        // 可以设置间隙宽度
        // bar.setGapWidth(200);
        // 开始画图
        chart.plot(data);
        Rectangle2D.Double rect = new Rectangle2D.Double(700000, 500000, 7000000, 5000000);
        // 把柱状图加到幻灯片里,指定画布
        slide6.addChart(chart, rect);
    }

private static void createSlideWithChart(XMLSlideShow ppt, String chartTitle, String[] series, String[] categories, Double[] values1, Double[] values2) {
        XSLFSlide slide = ppt.createSlide();
        XSLFChart chart = ppt.createChart();
        Rectangle2D rect2D = new java.awt.Rectangle(fromCM(1.5), fromCM(4), fromCM(22), fromCM(14));
        // 把柱状图加到幻灯片里,指定画布
        slide.addChart(chart, rect2D);
        setBarData(chart, chartTitle, series, categories, values1, values2);
    }

    private static void createSlideWithChartOne(XMLSlideShow ppt, String chartTitle, String[] series, String[] categories, Double[] values, int valuesColumn) {
        XSLFSlide slide = ppt.createSlide();
        XSLFChart chart = ppt.createChart();
        Rectangle2D rect2D = new java.awt.Rectangle(fromCM(1.5), fromCM(4), fromCM(22), fromCM(14));
        slide.addChart(chart, rect2D);
        setDoughnutData(chart, chartTitle, series, categories, values, valuesColumn);
    }

    private static int fromCM(double cm) {
        return (int)(Math.rint(cm * Units.EMU_PER_CENTIMETER));
    }

    private static void setBarData(XSLFChart chart, String chartTitle, String[] series, String[] categories, Double[] values1, Double[] values2) {

        XDDFChartAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);

        bottomAxis.setTitle(series[2]);

        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        leftAxis.setTitle(series[0] + "," + series[1]);
        leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
        leftAxis.setMajorTickMark(AxisTickMark.OUT);
        leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

        final int numOfPoints = categories.length;

        final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, COLUMN_LANGUAGES, COLUMN_LANGUAGES));

        final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, COLUMN_COUNTRIES, COLUMN_COUNTRIES));

        final String valuesDataRange2 = chart.formatRange(new CellRangeAddress(1, numOfPoints, COLUMN_SPEAKERS, COLUMN_SPEAKERS));

        // 底部类别的数据源
        final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, COLUMN_LANGUAGES);

        // 这是第一个柱状图的数据源
        final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values1, valuesDataRange, COLUMN_COUNTRIES);
        valuesData.setFormatCode("General");

        values1[6] = 16.0;
        // 这是第二个柱状图的数据源
        final XDDFNumericalDataSource<? extends Number> valuesData2 = XDDFDataSourcesFactory.fromArray(values2, valuesDataRange2, COLUMN_SPEAKERS);
        valuesData2.setFormatCode("General");

        // 创建图表数据,第一个指定是什么图表 柱状图或者饼图,折线图都ok,
        XDDFBarChartData bar = (XDDFBarChartData)chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
        // 柱状图的类型
        bar.setBarGrouping(BarGrouping.CLUSTERED);

        // 把第一组柱状图添加到图表数据里 返回一个系列数据
        // 设置第一个系列的名称 上面那个生成图表底部的示例的就是这里 ,第一个指定名称,第二个可以给一个单元格。两个参数可以有一个为null
        XDDFBarChartData.Series series1 = (XDDFBarChartData.Series)bar.addSeries(categoriesData, valuesData);
        series1.setTitle(series[0], chart.setSheetTitle(series[COLUMN_COUNTRIES - 1], COLUMN_COUNTRIES));
        // 第二组
        XDDFBarChartData.Series series2 = (XDDFBarChartData.Series)bar.addSeries(categoriesData, valuesData2);
        series2.setTitle(series[1], chart.setSheetTitle(series[COLUMN_SPEAKERS - 1], COLUMN_SPEAKERS));
        // 是否设置不同的颜色 false就行
        bar.setVaryColors(true);
        // 柱状图的方向
        bar.setBarDirection(BarDirection.COL);
        // 可以设置间隙宽度
        // bar.setGapWidth(200);
        // 开始画图
        chart.plot(bar);

        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.LEFT);
        legend.setOverlay(false);

        chart.setTitleText(chartTitle);
        chart.setTitleOverlay(false);
        chart.setAutoTitleDeleted(false);
    }
private static void setDoughnutData(XSLFChart chart, String chartTitle, String[] series, String[] categories, Double[] values, int valuesColumn) {
        final int numOfPoints = categories.length;
        final String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, COLUMN_LANGUAGES, COLUMN_LANGUAGES));
        final String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, valuesColumn, valuesColumn));
        final XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, COLUMN_LANGUAGES);
        final XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(values, valuesDataRange, valuesColumn);
        valuesData.setFormatCode("General");

        XDDFDoughnutChartData data = (XDDFDoughnutChartData)chart.createData(ChartTypes.DOUGHNUT, null, null);
        XDDFDoughnutChartData.Series series1 = (XDDFDoughnutChartData.Series)data.addSeries(categoriesData, valuesData);
        series1.setTitle(series[0], chart.setSheetTitle(series[valuesColumn - 1], valuesColumn));

        data.setVaryColors(true);
        // data.setHoleSize(42);
        // data.setFirstSliceAngle(90);
        chart.plot(data);

        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.LEFT);
        legend.setOverlay(false);

        chart.setTitleText(chartTitle);
        chart.setTitleOverlay(false);
        chart.setAutoTitleDeleted(false);
    }

    private static void createTextList(XMLSlideShow ppt) {
        XSLFSlide slide = ppt.createSlide();
        XSLFTextBox shape = slide.createTextBox();
        shape.setAnchor(new Rectangle(50, 50, 400, 200));

        XSLFTextParagraph p1 = shape.addNewTextParagraph();
        p1.setIndentLevel(0);
        p1.setBullet(true);
        XSLFTextRun r1 = p1.addNewTextRun();
        r1.setText("r1");

        XSLFTextParagraph p2 = shape.addNewTextParagraph();
        // 文本前缩进
        p2.setLeftMargin(60d);
        p2.setIndent(-40d);
        p2.setBullet(true);
        // 自定义颜色
        p2.setBulletFontColor(Color.red);
        p2.setBulletFont("Wingdings");
        p2.setBulletCharacter("\u0075");
        p2.setIndentLevel(1);
        XSLFTextRun r2 = p2.addNewTextRun();
        r2.setText("Bullet2");

        XSLFTextParagraph p3 = shape.addNewTextParagraph();
        p3.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenRight, 1);
        p3.setIndentLevel(2);
        XSLFTextRun r3 = p3.addNewTextRun();
        r3.setText("Numbered List Item - 1");

        XSLFTextParagraph p4 = shape.addNewTextParagraph();
        p4.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenRight, 2);
        p4.setIndentLevel(2);
        XSLFTextRun r4 = p4.addNewTextRun();
        r4.setText("Numbered List Item - 2");

        XSLFTextParagraph p5 = shape.addNewTextParagraph();
        p5.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenRight, 3);
        p5.setIndentLevel(2);
        XSLFTextRun r5 = p5.addNewTextRun();
        r5.setText("Numbered List Item - 3");

        shape.resizeToFitText();
    }
public static void createTableOne(XMLSlideShow ppt) {
        XSLFSlide slide = ppt.createSlide();
        XSLFTable tbl = slide.createTable();
        tbl.setAnchor(new Rectangle(50, 50, 450, 300));
        int numColumns = 3;
        int numRows = 5;
        XSLFTableRow headerRow = tbl.addRow();
        headerRow.setHeight(50);
        // header
        for (int i = 0; i < numColumns; i++) {
            XSLFTableCell th = headerRow.addCell();
            XSLFTextParagraph p = th.addNewTextParagraph();
            p.setTextAlign(TextParagraph.TextAlign.CENTER);
            XSLFTextRun r = p.addNewTextRun();
            r.setText("Header " + (i + 1));
            r.setBold(true);
            r.setFontColor(Color.white);
            th.setFillColor(new Color(79, 129, 189));
            th.setBorderWidth(TableCell.BorderEdge.bottom, 2.0);
            th.setBorderColor(TableCell.BorderEdge.bottom, Color.white);

            tbl.setColumnWidth(i, 150); // all columns are equally sized
        }
        // rows
        for (int rownum = 0; rownum < numRows; rownum++) {
            XSLFTableRow tr = tbl.addRow();
            tr.setHeight(50);
            // header
            for (int i = 0; i < numColumns; i++) {
                XSLFTableCell cell = tr.addCell();
                XSLFTextParagraph p = cell.addNewTextParagraph();
                XSLFTextRun r = p.addNewTextRun();

                r.setText("Cell " + (i + 1));
                if (rownum % 2 == 0) {
                    cell.setFillColor(new Color(208, 216, 232));
                } else {
                    cell.setFillColor(new Color(233, 247, 244));
                }
            }
        }
    }

    private static void createTable(XMLSlideShow ppt) {
        XSLFSlide slide5 = ppt.createSlide();
        // 创建文本框
        XSLFTextBox textBox4 = slide5.createTextBox();
        // x y设置距离 w h 设置大小
        textBox4.setAnchor(new Rectangle2D.Double(300, 50, 100, 50));
        textBox4.addNewTextParagraph().addNewTextRun().setText("表格测试");
        // 渲染的基础数据
        Object[][] datas = {{"aaaaa", "", ""}, {"bb", "ccc", "dddd"}, {"A", 1, 2}, {"B", 3, 4}};
        // 创建表格
        XSLFTable table = slide5.createTable();
        // 定位 如果不通过setAnchor()方法指定坐标,则幻灯片中不会显示该文本元素。
        table.setAnchor(new Rectangle2D.Double(10, 50, 0, 0));
        for (int i = 0; i < datas.length; i++) {
            // 创建表格行
            XSLFTableRow tableRow = table.addRow();
            for (int j = 0; j < datas[i].length; j++) {
                // 创建表格单元格
                XSLFTableCell tableCell = tableRow.addCell();
                XSLFTextParagraph xslfTextRuns = tableCell.addNewTextParagraph();
                XSLFTextRun tr = xslfTextRuns.addNewTextRun();
                tr.setText(String.valueOf(datas[i][j]));

                tableCell.setFillColor(Color.getColor("0xdd7e6b"));
                xslfTextRuns.setTextAlign(TextParagraph.TextAlign.CENTER);
                tableCell.setVerticalAlignment(VerticalAlignment.MIDDLE);

                if (i == datas.length - 1 && j == 3 - 1) {
                    tr.setFontSize(16D);
                    tr.setBold(true);
                    tr.setItalic(true);
                    tr.setUnderlined(true);
                    tr.setFontFamily("\u5b8b\u4f53");
                    tr.setFontColor(Color.RED);
                }
                // 表格宽度 和颜色
                tableCell.setBorderWidth(TableCell.BorderEdge.bottom, 1);
                tableCell.setBorderWidth(TableCell.BorderEdge.left, 1);
                tableCell.setBorderWidth(TableCell.BorderEdge.top, 1);
                tableCell.setBorderWidth(TableCell.BorderEdge.right, 1);

                tableCell.setBorderColor(TableCell.BorderEdge.bottom, Color.black);
                tableCell.setBorderColor(TableCell.BorderEdge.left, Color.black);
                tableCell.setBorderColor(TableCell.BorderEdge.top, Color.black);
                tableCell.setBorderColor(TableCell.BorderEdge.right, Color.black);
            }
            // 每行高度
            tableRow.setHeight(30);
        }
        // 设置列宽
        table.setColumnWidth(0, 150);
        table.setColumnWidth(1, 150);
        table.setColumnWidth(2, 250);
        // 合并单元格
        table.mergeCells(0, 0, 0, 2);
    }

第二种:模板文件

 

 

private static void createPPTByTemplate() throws Exception {
        // 读取模板文件
        ClassPathResource resource = new ClassPathResource("ppt-template.pptx");
        // 根据模板,创建一个新的ppt文档
        XMLSlideShow ppt = new XMLSlideShow(resource.getInputStream());
        // 替换模板内容
        // 得到每页ppt
        List<XSLFSlide> slides = ppt.getSlides();
        // 遍历ppt,填充模板
        for (int i = 0; i < slides.size(); i++) {
            // 遍历每页ppt中待填充的形状组件
            String slideName = slides.get(i).getSlideName();
            System.out.println(slideName);
            for (XSLFShape shape : slides.get(i).getShapes()) {
                if (shape instanceof TextShape) {
                    // 替换文本
                    TextShape textShape = (TextShape) shape;
                    TextRun textRun;
                    String text = textShape.getText().trim();
                    switch (text) {
                        case "username":
                            textRun = textShape.setText("张三");
                            textRun.setFontFamily("宋体(正文)");
                            textRun.setFontSize(18.0);
                            break;
                        case "dates":
                            textRun = textShape.setText("2022-10-30");
                            textRun.setFontFamily("宋体(正文)");
                            textRun.setFontSize(18.0);
                            break;
                        case "desc":
                            textRun = textShape.setText("描述");
                            textRun.setFontFamily("宋体(正文)");
                            textRun.setFontSize(18.0);
                            textRun.setFontColor(Color.green);
                            break;
                        case "prec":
                            textRun = textShape.setText("23%");
                            textRun.setFontFamily("宋体(正文)");
                            textRun.setFontSize(18.0);
                            textRun.setFontColor(Color.red);
                            break;
                    }
                } else if (shape instanceof PictureShape) {
                    // 替换图片
                    PictureData pictureData = ((PictureShape) shape).getPictureData();
                    byte[] bytes = IOUtils.toByteArray(new FileInputStream("./doc/3.png"));
                    pictureData.setData(bytes);
                } else if (shape instanceof XSLFTable) {
                    // 表格
                    XSLFTable xslfTable = ((XSLFTable) shape);
                    List<XSLFTableRow> rowList = xslfTable.getRows();
                    //每一行
                    for (int i1 = 0; i1 < rowList.size(); i1++) {
                        //每一列
                        rowList.get(i1).setHeight(12);
                        List<XSLFTableCell> cells = rowList.get(i1).getCells();
                        for (int a1 = 0; a1 < cells.size(); a1++) {
                            cells.get(a1).setText("cells" + a1);
                        }
                    }
                    //XSLFGraphicFrame
                }else if(shape instanceof XSLFGraphicFrame){
                    XSLFGraphicFrame xslfGraphicFrame=(XSLFGraphicFrame)shape;
                    System.out.println("图形");
                }
            }
        }
        // 将新的ppt写入到指定的文件中
        FileOutputStream outputStream = new FileOutputStream("./doc/33.pptx");
        ppt.write(outputStream);
        outputStream.close();

    }

3、EXECL文件

XLSXLSX
只能打开xls格式,无法直接打开xlsx格式可以直接打开xls、xlsx格式
只有65536行、256列可以有1048576行、16384列
占用空间大占用空间小,运算速度也会快一点
ExcelPOI XLSPOI XLSX(Excel 2007+)
Excel 文件HSSFWorkbook (xls)XSSFWorkbook(xlsx)
Excel 工作表HSSFSheetXSSFSheet
Excel 行HSSFRowXSSFRow
Excel 单元格HSSFCellXSSFCell
Excel 单元格样式HSSFCellStyleHSSFCellStyle
Excel 颜色HSSFColorXSSFColor
Excel 字体HSSFFontXSSFFont

1.导入

/**
     * 生成 execl
     * @return
     */
    public static SXSSFWorkbook generateExcelWorkbook() {

        SXSSFWorkbook workbook = new SXSSFWorkbook();
        Sheet sheet = workbook.createSheet();

        int rows = 1;
        int cols = 1;
        // 表头
        Row head = sheet.createRow(rows++);
        String[] columns = new String[] {"标题一", "标题二", "标题三", "标题四", "标题五"};
        //每行宽度
        int[] colWidths = new int[] {5000, 5000, 5000, 5000, 5000};

        CellStyle headStyle = workbook.createCellStyle();
        // 字体
        Font font = workbook.createFont();
        font.setBold(true);
        headStyle.setFont(font);

        // 位置
        headStyle.setAlignment(HorizontalAlignment.CENTER);
        headStyle.setVerticalAlignment(VerticalAlignment.TOP);

        // 设置表格样式
        headStyle.setBorderBottom(BorderStyle.THIN);
        headStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        headStyle.setBorderLeft(BorderStyle.THIN);
        headStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        headStyle.setBorderRight(BorderStyle.THIN);
        headStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        headStyle.setBorderTop(BorderStyle.THIN);
        headStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());

        headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        for (int i = 0; i < columns.length; ++i) {
            sheet.setColumnWidth(cols, colWidths[i]);
            //设置样式
            Cell cell = head.createCell(cols++);
            cell.setCellStyle(headStyle);
            cell.setCellValue(columns[i]);
        }
        // 设置表格样式
        CellStyle contentStyle = workbook.createCellStyle();
        // 字体
        Font contentFont = workbook.createFont();
        contentFont.setBold(true);
        contentStyle.setFont(contentFont);

        // 位置
        contentStyle.setAlignment(HorizontalAlignment.CENTER);
        contentStyle.setVerticalAlignment(VerticalAlignment.TOP);

        // 设置表格样式
        contentStyle.setBorderBottom(BorderStyle.THIN);
        contentStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        contentStyle.setBorderLeft(BorderStyle.THIN);
        contentStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        contentStyle.setBorderRight(BorderStyle.THIN);
        contentStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        contentStyle.setBorderTop(BorderStyle.THIN);
        contentStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());

        //填充数据
        List<Integer> dataList=new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            dataList.add(i);
        }
        List<List<Integer>> subList = Lists.partition(dataList, 5);
        for (List<Integer> list : subList) {
            cols = 1;
            Row row = sheet.createRow(rows++);
            for (Integer value : list) {
                Cell cell = row.createCell(cols++);
                cell.setCellStyle(contentStyle);
                cell.setCellValue(value);
            }
        }
        return workbook;
    }

2.导出

public static void parseExeclFile(String filePath) throws Exception {
        XSSFWorkbook book = new XSSFWorkbook(new FileInputStream(filePath));
        XSSFSheet sheet = book.getSheetAt(0);
        // 解析数据
        int cols;
        for (int i = 1; i < sheet.getLastRowNum(); i++) {
            // 排除 表头
            XSSFRow row = sheet.getRow(i + 1);
            cols = 1;
            for (int j = 0; j < 5; j++) {
                int cellLongValue = Integer.parseInt("" + (int)(row.getCell(cols++)).getNumericCellValue());
                System.out.print(cellLongValue);
                System.out.print(" ");
            }
            System.out.println("\n");
        }

        book.close();
    }

测试:

    public static void main(String[] args) throws Exception{

        //导入 execl
//        SXSSFWorkbook sxssfWorkbook = generateExcelWorkbook();
//        sxssfWorkbook.write(new FileOutputStream("./doc/a.xlsx"));
//        sxssfWorkbook.dispose();

        //解析 execl
        parseExeclFile("./doc/a.xlsx");


    }

 

Poi官网

Poi-tl官网

代码地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/47417.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【uniapp小程序】路由跳转navigator传参封装

文章目录&#x1f34d;前言&#x1f34b;正文1、看官网1.1 navigator API 介绍1.2、路由跳转参数传递1.3、五种常见的跳转方式1.3.1 uni.navigateTo(OBJECT)1.3.2 uni.redirectTo(OBJECT)1.3.3 uni.reLaunch(OBJECT)1.3.4 uni.switchTab(OBJECT)1.3.5 uni.navigateBack(OBJECT)…

Ensp用windows回环口连接cloud配置

Ensp模拟通过本机&#xff08;windows&#xff09;用python脚本批量配置华为数通设备时&#xff0c;为了避免对内网资源的浪费最好用回环口&#xff08;loopback&#xff09;。 一、windows开启loopback虚拟接口 概要&#xff1a; right click on window start menu icon an…

【C++】类型转换

目录 一、C语言风格类型转换 二、C风格类型转换 1.static_case 2.reinterpret_case 3、const_case 4、dynamic_case 三、RTTI 总结 一、C语言风格类型转换 在C语言中&#xff0c;如果赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不匹配&#xff0c;或者返…

N-Gram模型介绍

N-gram是一种基于统计语言模型的算法&#xff0c;基本思想是将文本内容按照字节进行大小为N的滑动窗口操作&#xff0c;形成了长度是N的字节片段序列。 每一个字节片段称为gram&#xff0c;对所有gram的出现频度进行统计&#xff0c;并且按照事先设定好的阈值进行过滤&#xf…

PowerQuery:使用正则表达式

博客来源于我的语雀专栏&#xff1a;R 语言 语雀 更多内容同步更新请关注我的语雀&#xff1a;令平子 语雀 参考资料&#xff1a;部分已引用到各段落 在Power Query中使用正则表达式 Power query 自定义正则表达式函数 新建空白查询&#xff0c;粘贴以下代码&#xff0c;使用…

gcc: error trying to exec ‘cc1plus‘: execvp: no such file or directory

该问题是缺少gcc文件&#xff0c;或者gcc与g版本不匹配问题 问题来源1&#xff1a;系统文件的缺失或者不匹配 按照如下方法测试 安装主要是利用apt-get安装&#xff0c;如果没有root权限的话&#xff0c;只能下载源码进行编译安装&#xff0c;然后添加路径环境&#xff0c;安…

JavaWeb简单实例——Ajax请求

简单介绍&#xff1a; 在上一章节我们展示了关于jQuery的一些基本操作&#xff0c;接下来我们就要进行Ajax的一些基础操作&#xff0c;在真正执行操作之前&#xff0c;我们还需要一点前置的准备&#xff0c;就是关于发送和请求JSON数据的准备。 请求JSON数据&#xff1a; JS…

板卡测评 | 基于TI AM5708开发板——ARM+DSP多核异构开发案例分享

本次测评板卡是创龙科技旗下的TL570x-EVM,它是一款基于TI Sitara系列AM5708ARM Cortex-A15+浮点DSPC66x处理器设计的异构多核SOC评估板,由核心板和评估底板组成。核心板经过专业的PCB Layout和高低温测试验证,稳定可靠,可满足各种工业应用环境。 评估板接口资源丰富,引出…

你还不懂《顺序表》?那就不要错过这篇文章!!!

&#x1f387;&#x1f387;&#x1f387;作者&#xff1a; 小鱼不会骑车 &#x1f386;&#x1f386;&#x1f386;专栏&#xff1a; 《java练级之旅》 &#x1f393;&#x1f393;&#x1f393;个人简介&#xff1a; 一名专科大一在读的小比特&#xff0c;努力学习编程是我…

怎样翻译文本?这三种翻译方法我经常使用

大家是不是还在将收到的文本或资料一句一句地复制到浏览器去翻译&#xff0c;再将翻译结果粘贴回文内呢&#xff1f;这种方法固然可以&#xff0c;但要是遇到需要翻译的文本内容比较多的情况时&#xff0c;就会很浪费时间和精力&#xff0c;如果恰好被英语不好的小伙伴遇到这种…

NoSQL数据库之Redis2

Redis 事务 事务的基础概念 关于事务最常见的例子就是银行转账&#xff0c;A 账户给 B 账户转账一个亿 (T1)&#xff0c;买一块地盖房子。在这种交易的过程中&#xff0c;有几个问题值得思考&#xff1a; 如何同时保证上述交易中&#xff0c;A账户总金额减少一个亿&#xff…

[附源码]Python计算机毕业设计Django的毕业生就业系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

蜂鸟E203学习笔记(四)——取指

1.1 取值概述 1.1.1 如何快速取指 首先要保证存储器的读延时足够小&#xff0c;通常使用指令紧耦合存储器&#xff08;ITCM&#xff09;和指令缓存器&#xff08;ICache&#xff09;。 ITCM通常使用离处理核很近的SRAM因此实现极短的延时。但是没有过大的存储空间&#xff0…

社区系统项目复盘-2

文章目录登录模块注册登录账号设置登录模块 重要知识点&#xff1a; ThreadLocal&#xff0c;Hostholder采用Threadlocal持有用户信息&#xff0c;用于代替session对象 ThreadLocal采用线程隔离的方式存放数据&#xff0c;可以避免多线程之间出现数据访问冲突。ThreadLocal提…

小程序全局配置文件以及常用配置项

一、window常用配置 1.小程序根目录下的app.json文件时小程序的全局配置文件。常用配置项如下&#xff1a; ① pages 记录当前小程序所有页面的存放路径 ② window 全局设置小程序窗口的外观 ③ tabBar 设置小程序底部的tabBar效果 ④ style 是否启用新版的组件样式 …

【Spring项目中的Service理解】

目录 1. Spring项目中的核心组成部分 2. Spring项目中的Service 2.1 Service的功能作用 2.2 Service的实现 1. Spring项目中的核心组成部分 项目的核心组成部分图解&#xff1a; 2. Spring项目中的Service 2.1 Service的功能作用 Service是项目中用于处理业务逻辑的&#x…

【学习笔记66】JavaScript的深浅拷贝

一、赋值 只要是引用数据类型, 那么在赋值的时候, 就是引用地址的传递// 赋值:字符串const s1 123;let s2 s1; // 赋值console.log(s2 s1); // trues2 456;console.log(s1); // 123console.log(s2); // 456 let o1 { a: 1 };let o2 o1; // 赋值console.log…

【iOS】—— GET和POST以及AFNetworking框架

GET和POST以及AFNetworking框架 文章目录GET和POST以及AFNetworking框架GET和POSTGET和POST区别GETGET请求步骤GET请求代码POSTPOST请求步骤POST请求代码AFNetworking简介添加头文件GETGET方法GET方法参数GET方法代码样例POSTPOST方法第一种&#xff1a;第二种&#xff1a;先来…

[附源码]计算机毕业设计springboot防疫物资捐赠

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

springboot+jsp学生成绩查询考务系统

众所周知&#xff0c;现代信息技术是现代教育技术的基础和核心&#xff0c;培养和创新型的人才&#xff0c;必须依靠现代教育技术。从这一层意义上讲&#xff0c;我们说掌握一定的计算机应用技能已经成为国家未来的合格建设者的必备素质&#xff0c;所以现在在大学中对非计算机…