java中使用poi生成word
项目当中需要后端生成word,当中包含表格,折线图,文字等内容,顺手写了一个工具类,分享一下,欢迎大佬批评指正
先上pom
<poi.version>4.1.2</poi.version>
<commons-collections4.version>4.4</commons-collections4.version>
<commons-codec.version>1.13</commons-codec.version>
<commons-compress.version>1.19</commons-compress.version>
<xmlbeans.version>3.1.0</xmlbeans.version>
<ooxml-schemas.version>1.4</ooxml-schemas.version>
<!-- poi相关 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apachemons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>org.apachemons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>${xmlbeans.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>${ooxml-schemas.version}</version>
</dependency>
工具类
工具类当中的BussinessException是我自定义的业务错误
import iie.cas.channelcommon.exception.BussinessException;
import lombok.Data;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
/**
* poi 相关工具类
*
* @author: yxc
* @time: 2022/1/10 11:04
**/
public class PoiUtils {
/**
* 图数据对象
* 仅代表每一个数据轴
*/
@Data
public static class ChartValue {
/**
* 标题
*/
private String title;
/**
* 值列表,与下面intList二选一
*/
private List<String> strList = new ArrayList<>();
/**
* 值列表,与上面strList二选一
*/
private List<Integer> intList = new ArrayList<>();
public ChartValue(String title) {
this.title = title;
}
}
/**
* 创建折线图
*
* @author yxc
* @date 2022/1/18 9:11
* @param document: word的document对象
* @param title: 图标题
* @param valueTitle: 纵坐标标题
* @param category: 横坐标数据
* @param values: 纵坐标数据,可以为多个
* @return void
**/
public static void createWordLineChartXML(XWPFDocument document,
String title,
String valueTitle,
ChartValue category,
ChartValue... values) throws IOException, InvalidFormatException {
// create the chart
XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
// 标题
chart.setTitleText(title);
// 标题覆盖
chart.setTitleOverlay(false);
// 图例位置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.TOP);
// 分类轴标(X轴),标题位置
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setTitle(category.getTitle());
// 值(Y轴)轴,标题位置
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setTitle(valueTitle);
// 设置x轴数据
XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(category.getStrList().toArray(new String[]{}));
// LINE:折线图,
XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
for (ChartValue value : values) {
// 设置y轴数据
XDDFNumericalDataSource<Integer> area = XDDFDataSourcesFactory.fromArray(value.getIntList().toArray(new Integer[]{}));
// 图表加载数据,折线1
XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(countries, area);
// 折线图例标题
series1.setTitle(value.getTitle(), null);
// 直线
series1.setSmooth(false);
// 设置标记大小
series1.setMarkerSize((short) 6);
// 设置标记样式,星星
// series1.setMarkerStyle(MarkerStyle.STAR);
}
// 绘制
chart.plot(data);
// 打印图表的xml
// System.out.println(chart.getCTChart());
}
/**
* 创建标题
*
* @author yxc
* @date 2022/1/18 9:26
* @param document: word的document对象
* @param title: 标题
* @param subTitle: 副标题
* @return void
**/
public static void createTitle(XWPFDocument document, String title, String subTitle) {
if (StringUtils.isEmpty(title)) {
throw new BussinessException("标题不能为空");
}
// 创建段落
XWPFParagraph titleParagraph = document.createParagraph();
XWPFRun titleRun = titleParagraph.createRun();
titleRun.setText(title);
// 字号
titleRun.setFontSize(20);
// 加粗
titleRun.setBold(true);
// 居中
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
if (StringUtils.isNotEmpty(subTitle)) {
// 处理父标题
XWPFParagraph subTitleParagraph = document.createParagraph();
XWPFRun subTitleRun = subTitleParagraph.createRun();
subTitleRun.setText(subTitle);
// 字号
subTitleRun.setFontSize(14);
// 加粗
subTitleRun.setBold(true);
// 居中
subTitleParagraph.setAlignment(ParagraphAlignment.CENTER);
}
}
/**
* 创建段落
*
* @author yxc
* @date 2022/1/18 10:14
* @param document: word的document对象
* @param title: 段落标题,可以为空
* @param paragraphStr: 段落内容
* @return void
**/
public static void createParagraph(XWPFDocument document, String title, String paragraphStr) {
if (StringUtils.isEmpty(paragraphStr)) {
throw new BussinessException("段落不能为空");
}
if (StringUtils.isNotEmpty(title)) {
// 段落标题
// 创建段落
XWPFParagraph titleParagraph = document.createParagraph();
XWPFRun titleRun = titleParagraph.createRun();
titleRun.setText(title);
// 字号
titleRun.setFontSize(16);
// 加粗
titleRun.setBold(true);
// 居中
titleParagraph.setAlignment(ParagraphAlignment.LEFT);
}
// 创建段落
XWPFParagraph paragraph = document.createParagraph();
XWPFRun paragraphRun = paragraph.createRun();
// 设置文字
paragraphRun.setText(paragraphStr);
// 字号
paragraphRun.setFontSize(14);
// 两端对齐
paragraph.setAlignment(ParagraphAlignment.BOTH);
// 首行缩进
paragraph.setFirstLineIndent(600);
// paragraph.setIndentFromLeft(14 * 2);
}
/**
* 表格属性对象
*/
@Data
public static class TableValue {
/**
* 列数
*/
private int colNum;
/**
* 行数
*/
private int rowNum;
/**
* 标题
*/
private List<String> titleList = new ArrayList<>();
/**
* 内容
*/
private List<List<String>> valueList = new ArrayList<>();
/**
* 表格标题
*/
private String tableTitle;
public TableValue(int colNum, int rowNum) {
this.colNum = colNum;
this.rowNum = rowNum;
}
public TableValue(int colNum, int rowNum, String tableTitle) {
this.colNum = colNum;
this.rowNum = rowNum;
this.tableTitle = tableTitle;
}
}
/**
* 创建表格
*
* @author 杨旭晨
* @date 2022/1/18 17:38
* @param document: word对应的document对象
* @param tableValue: 表格属性对象
* @return void
**/
public static void createTable(XWPFDocument document, TableValue tableValue) {
if (StringUtils.isNotEmpty(tableValue.getTableTitle())) {
// 创建段落
XWPFParagraph titleParagraph = document.createParagraph();
XWPFRun titleRun = titleParagraph.createRun();
titleRun.setText(tableValue.tableTitle);
// 字号
titleRun.setFontSize(16);
// 加粗
titleRun.setBold(true);
// 居中
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
}
XWPFTable table = document.createTable(tableValue.rowNum, tableValue.colNum);
// 表格宽度
table.setWidth(100);
// 宽度类型 百分比
table.setWidthType(TableWidthType.PCT);
// 水平居中
table.setTableAlignment(TableRowAlign.CENTER);
if (tableValue.getTitleList() != null && !tableValue.getTitleList().isEmpty()) {
// 标题行不为空,添加标题行
XWPFTableRow titleRow = table.getRow(0);
// 设置高度
titleRow.setHeight(300);
// 设置标题行
List<String> titleList = tableValue.getTitleList();
for (int i = 0; i < titleList.size(); i++) {
XWPFTableCell cell = titleRow.getCell(i);
// 以段落的形式添加文字
XWPFParagraph cellParagraph = cell.getParagraphArray(0);
XWPFRun cellRun = cellParagraph.createRun();
// 文字
cellRun.setText(titleList.get(i));
// 居中
cellParagraph.setAlignment(ParagraphAlignment.CENTER);
// 字号
cellRun.setFontSize(12);
// 加粗
cellRun.setBold(true);
}
}
// 内容行
List<List<String>> valueList = tableValue.getValueList();
for (int i = 0; i < valueList.size(); i++) {
// 排除第一行,标题行
XWPFTableRow valueRow = table.getRow(i + 1);
// 设置高度
valueRow.setHeight(300);
List<String> values = valueList.get(i);
for (int j = 0; j < values.size(); j++) {
XWPFTableCell cell = valueRow.getCell(j);
// 用段落形式添加文字
XWPFParagraph cellParagraph = cell.getParagraphArray(0);
XWPFRun cellRun = cellParagraph.createRun();
// 文字
cellRun.setText(values.get(j));
// 居中
cellParagraph.setAlignment(ParagraphAlignment.CENTER);
// 字号
cellRun.setFontSize(12);
// 不加粗
cellRun.setBold(false);
}
}
setTableHeight(table, 600, STVerticalJc.CENTER);
}
/**
* 设置表格高度
*
* @author 杨旭晨
* @date 2022/1/18 17:38
* @param infoTable: 表格
* @param heigth: 设置的高度
* @param vertical: xxx
* @return void
**/
private static void setTableHeight(XWPFTable infoTable, int heigth, STVerticalJc.Enum vertical) {
List<XWPFTableRow> rows = infoTable.getRows();
for(XWPFTableRow row : rows) {
CTTrPr trPr = row.getCtRow().addNewTrPr();
CTHeight ht = trPr.addNewTrHeight();
ht.setVal(BigInteger.valueOf(heigth));
List<XWPFTableCell> cells = row.getTableCells();
for(XWPFTableCell tableCell : cells ) {
CTTcPr cttcpr = tableCell.getCTTc().addNewTcPr();
cttcpr.addNewVAlign().setVal(vertical);
}
}
}
/**
* 添加下一页分隔符
*
* @author yxc
* @date 2022/1/18 11:21
* @param document: word的document对象
* @return void
**/
public static void createNextPageChar(XWPFDocument document) {
XWPFParagraph paragraph = document.createParagraph();
paragraph.setPageBreak(true);
}
/**
* 将word输出为文件,返回文件路径
*
* @author yxc
* @date 2022/1/18 9:12
* @param outFile: 输出文件
* @param document: word的document对象
* @return java.lang.String
**/
public static String writeFile(File outFile, XWPFDocument document) {
if (outFile == null) {
throw new BussinessException("文件为空");
}
if (!outFile.getParentFile().exists()) {
// 文件夹不存在
outFile.getParentFile().mkdirs();
}
try (FileOutputStream fos = new FileOutputStream(outFile)) {
document.write(fos);
} catch (Exception e) {
throw new BussinessException("文件写入失败");
}
return outFile.getPath();
}
}
更多推荐
java poi生成word
发布评论