目录
一、概述
二、使用介绍
第一种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文件
XLS | XLSX |
---|---|
只能打开xls格式,无法直接打开xlsx格式 | 可以直接打开xls、xlsx格式 |
只有65536行、256列 | 可以有1048576行、16384列 |
占用空间大 | 占用空间小,运算速度也会快一点 |
Excel | POI XLS | POI XLSX(Excel 2007+) |
---|---|---|
Excel 文件 | HSSFWorkbook (xls) | XSSFWorkbook(xlsx) |
Excel 工作表 | HSSFSheet | XSSFSheet |
Excel 行 | HSSFRow | XSSFRow |
Excel 单元格 | HSSFCell | XSSFCell |
Excel 单元格样式 | HSSFCellStyle | HSSFCellStyle |
Excel 颜色 | HSSFColor | XSSFColor |
Excel 字体 | HSSFFont | XSSFFont |
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官网
代码地址