import lombok.Data;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.List;
/**
* 动态word生成
*/
@Data
public class WordUtil {
//标题
private String tableName;
private List<Directory> directory;
@lombok.Data
static class Directory {
//目录缩进层级
private int isHierarchy;
//01 :表格,02,文本,03附件
private String type;
//type为02时直接赋值
private String text;
//数据
private List<Data> data;
}
@lombok.Data
static class Data {
//数据
private List<String[]> values;
//水平合并单元格
private String colSpan;
//垂直合并单元格
private String rowSpan;
}
public static void Word(WordUtil map, HttpServletResponse response) throws IOException {
OutputStream outputStream = null;
try {
//创建word文档对象
XWPFDocument document = new XWPFDocument();
if (StringUtil.isNotEmpty(map.getTableName())) {
//这行代码是创建标题
XWPFParagraph title = document.createParagraph();
XWPFRun titleRun = title.createRun();
title.setAlignment(ParagraphAlignment.valueOf(STJc.INT_CENTER));
titleRun.setFontSize(20);
titleRun.setFontFamily("宋体");
titleRun.setBold(true);
titleRun.setText(map.getTableName());
titleRun.addBreak(); //换行
}
//获取数据
List<Directory> list = map.getDirectory();
if (ListUtil.isNotEmpty(list)) {
for (int i = 0; i < list.size(); i++) {
//目录缩进层级
int isHierarchy = list.get(i).getIsHierarchy();
//01 :表格,02,文本,03附件
String type = list.get(i).getType();
String text = list.get(i).getText();
//data
List<Data> data = list.get(i).getData();
if ("01".equals(type)) {
if (ListUtil.isEmpty(data)) {
continue;
}
List<String[]> length = data.get(0).getValues();
//创建表格的第一步
XWPFTable table = document.createTable(data.size(), length.get(0).length);
CTTblPr tablePr = table.getCTTbl().addNewTblPr();
CTTblWidth width = tablePr.addNewTblW();
width.setW(BigInteger.valueOf(8000));
width.setType(STTblWidth.DXA);
for (int i1 = 0; i1 < data.size(); i1++) {
if (StringUtil.isNotEmpty(data.get(i1).getColSpan())) {
String[] colSpans = data.get(i1).getColSpan().split(",");
if (colSpans.length > 0) {
//水平合并单元格
mergeCellsHorizontal(table, Integer.parseInt(colSpans[0]), Integer.parseInt(colSpans[1]), Integer.parseInt(colSpans[2]));
}
}
if (StringUtil.isNotEmpty(data.get(i1).getRowSpan())) {
String[] rowSpans = data.get(i1).getRowSpan().split(",");;
if (rowSpans.length > 0) {
//垂直合并单元格
mergeCellsVertically(table, Integer.parseInt(rowSpans[0]), Integer.parseInt(rowSpans[1]), Integer.parseInt(rowSpans[2]));
}
}
}
//填充表格内容
for (int i1 = 0; i1 < data.size(); i1++) {
List<String[]> values = data.get(i1).getValues();
for (int i2 = 0; i2 < values.size(); i2++) {
for (int i3 = 0; i3 < values.get(i2).length; i3++) {
XWPFTableCell cell = table.getRow(i1).getCell(i3);
CTTc ctTc = cell.getCTTc();
CTP ctP = (ctTc.sizeOfPArray() == 0) ? ctTc.addNewP() : ctTc.getPArray(0);
XWPFParagraph par = cell.getParagraph(ctP);
//设置水平居中
par.setAlignment(ParagraphAlignment.CENTER);
//设置垂直居中
par.setVerticalAlignment(TextAlignment.CENTER);
CTTcPr tcpr = ctTc.addNewTcPr();
CTTblWidth cellw = tcpr.addNewTcW();
cellw.setType(STTblWidth.DXA);
int floor = (int) Math.floor(8000 / values.size());
cellw.setW(new BigInteger(String.valueOf(floor)));
String value = values.get(i2)[i3];
cell.setText(value);
//单元格插入图片使用
//setCellImage(cell,"jpg",null);
}
}
}
}
if ("02".equals(type)) {
//添加第一个段落
XWPFParagraph paragraph = document.createParagraph();
//设置之段落左对齐
paragraph.setAlignment(ParagraphAlignment.valueOf(STJc.INT_LEFT));
// ---------以上是设置整段的,以下为设置内容
XWPFRun firstRun = paragraph.createRun();
firstRun.setFontSize(12);
firstRun.setFontFamily("宋体");
for (int i1 = 1; i1 < isHierarchy; i1++) {
firstRun.addTab();
}
firstRun.setText(text);
}
if ("03".equals(type)) {
}
}
}
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setCharacterEncoding("UTF-8");
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode("指导卡.docx", "UTF-8"));
//创建一个输出流
outputStream = response.getOutputStream();
document.write(outputStream);
} catch (Exception e) {
GlobalLogger.error("导出出现问题请排查:", e);
} finally {
if (outputStream != null) {
outputStream.close();
}
}
}
/**
* @Description: 跨列合并 水平合并单元格
* table要合并单元格的表格
* row 要合并哪一行的单元格 合并哪一行
* fromCell开始合并的单元格 合并的起点单元格
* toCell合并到哪一个单元格 合并的终点单元格
*/
public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
if (cellIndex == fromCell) {
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
} else {
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
/**
* @Description: 跨行合并 垂直合并单元格
* table要合并单元格的表格
* col要合并哪一列的单元格
* fromRow从哪一行开始合并单元格
* toRow合并到哪一个行
*/
public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
if (rowIndex == fromRow) {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
} else {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
}
}
}
//单元格写入图片
private static void setCellImage(XWPFTableCell cell, String type, InputStream is) throws Exception {
List<XWPFParagraph> paragraphs = cell.getParagraphs();
XWPFParagraph newPara = paragraphs.get(0);
XWPFRun imageCellRunn = newPara.createRun();
int format = 0;
if (type.endsWith("jpeg") || type.endsWith("jpg")) {
format = XWPFDocument.PICTURE_TYPE_JPEG;
} else {
format = XWPFDocument.PICTURE_TYPE_PNG;
}
imageCellRunn.addPicture(is, format, "图片名称", Units.toEMU(100), Units.toEMU(100)); // 200x200 pixels
}
}
参数如下:
{
"tableName": "标题",
"directory": [
{
"isHierarchy": "1",
"type": "02",
"text": "一级标题"
},
{
"isHierarchy": "2",
"type": "01",
"data": [
{
"values": [
[
"序号",
"序号",
"名称名称名称名称名称名称名称名称名称名称名称名称名称名称名称名称名称名称名称名称名称名称"
]
]
},
{
"values": [
[
"01",
"01",
"张三"
]
]
},
{
"values": [
[
"01",
"01",
"李四"
]
],
"colSpan":"2,0,1"
},
{
"values": [
[
"01",
"01",
"王五四"
]
]
}
]
}
]
}