poi可以操作excel表格和word文档,但是网上找的poi表格相关大多是操作excel表格,很少有word的复杂表格.
加上最近项目上也遇到了要使用java导出word多表格的问题.
开始网上找的例子大多是使用xml来操作word,后来多翻了点文章完成了word多表导出.
参考文章:
网上找的表格导出基础工具类
有使用到上面链接里面的XWPFHelperTable类和XWPFHelper类 多表导出也是基于上面博客的WordTest类修改的.
poi中相关控件中文文档
下面是我的工具类 调用里面的exportCheckWord方法得到文档对象
import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
/**
* 测试文档工具类
* @author 14277
*
*/
public class ExportWord {
private XWPFHelperTable xwpfHelperTable = null;
private XWPFHelper xwpfHelper = null;
public ExportWord() {
xwpfHelperTable = new XWPFHelperTable();
xwpfHelper = new XWPFHelper();
}
/**
* 创建好文档的基本 标题,表格 段落等部分
*
* @return
* @Author Huangxiaocong 2018年12月16日
*/
public XWPFDocument createXWPFDocument() {
XWPFDocument doc = new XWPFDocument();
return doc;
}
/**
* 创建表格的标题样式
*
* @param document
* @Author Huangxiaocong 2018年12月16日 下午5:28:38
*/
public void createTitleParagraph(XWPFDocument document) {
XWPFParagraph titleParagraph = document.createParagraph(); // 新建一个标题段落对象(就是一段文字)
titleParagraph.setAlignment(ParagraphAlignment.CENTER);// 样式居中
XWPFRun titleFun = titleParagraph.createRun(); // 创建文本对象
// titleFun.setText(titleName); //设置标题的名字
titleFun.setBold(true); // 加粗
titleFun.setColor("000000");// 设置颜色
titleFun.setFontSize(25); // 字体大小
// titleFun.setFontFamily("");//设置字体
// ...
titleFun.addBreak(); // 换行
}
/**
* 设置表格 主体内容
*
* @param document
* @param rows
* @param cols
* @Author Huangxiaocong 2018年12月16日
*/
public XWPFTable createTableParagraph(XWPFDocument document, List<List<String>> tableList) {
int rows = tableList.size();
int cols = tableList.get(0).size();
XWPFTable infoTable = document.createTable(rows, 4);
xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER);
// 合并表格
xwpfHelperTable.mergeCellsHorizontal(infoTable, 1, 1, cols - 1);
if (rows > 4) {
xwpfHelperTable.mergeCellsVertically(infoTable, 0, 3, cols - 1);
}
for (int col = 2; col < rows; col++) {
xwpfHelperTable.mergeCellsHorizontal(infoTable, col, 0, cols - 1);
}
// 设置表格样式
List<XWPFTableRow> rowList = infoTable.getRows();
for (int i = 0; i < rowList.size(); i++) {
XWPFTableRow infoTableRow = rowList.get(i);
List<XWPFTableCell> cellList = infoTableRow.getTableCells();
for (int j = 0; j < cellList.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphs().get(0);
if (i > 0) {
cellParagraph.setAlignment(ParagraphAlignment.LEFT);
} else {
cellParagraph.setAlignment(ParagraphAlignment.CENTER);
}
XWPFRun cellParagraphRun = cellParagraph.createRun();
cellParagraphRun.setFontSize(12);
}
}
xwpfHelperTable.setTableHeight(infoTable, 560, STVerticalJc.CENTER);
return infoTable;
}
/**
* 设置表格 人员内容
*
* @param document
* @param rows
* @param cols
* @Author Huangxiaocong 2018年12月16日
*/
public XWPFTable createTableParagraphRY(XWPFDocument document, List<List<String>> tableList) {
int rows = tableList.size();
int cols = tableList.get(0).size();
XWPFTable infoTable = document.createTable(rows, cols);
xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER);
int cosHeight = 0;
// 合并表格
for (int i = 0; i < tableList.size(); i++) {
if (i > 0 && !tableList.get(i).get(0).equals("")) {
String string = tableList.get(i).get(0);
String[] split = string.split(",");
int col = Integer.parseInt(split[1]);
cosHeight = i + col;
xwpfHelperTable.mergeCellsVertically(infoTable, 0, i, i + col - 1);
}
}
// 设置表格样式
List<XWPFTableRow> rowList = infoTable.getRows();
for (int i = 0; i < rowList.size(); i++) {
XWPFTableRow infoTableRow = rowList.get(i);
List<XWPFTableCell> cellList = infoTableRow.getTableCells();
for (int j = 0; j < cellList.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphs().get(0);
cellParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun cellParagraphRun = cellParagraph.createRun();
cellParagraphRun.setFontSize(12);
}
}
xwpfHelperTable.setTableHeight(infoTable, 560, STVerticalJc.CENTER);
return infoTable;
}
/**
* 设置表格 意见表
*
* @param document
* @param rows
* @param cols
* @Author Huangxiaocong 2018年12月16日
*/
public XWPFTable createTableParagraphJY(XWPFDocument document, List<List<String>> tableList, int jyCols) {
int rows = tableList.size();
int cols = tableList.get(0).size();
XWPFTable infoTable = null;
// 合并表格
if (jyCols < 6) {
infoTable = document.createTable(2, 6);
xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER);
xwpfHelperTable.mergeCellsHorizontal(infoTable, 1, 1, 5);
} else if (6 <= jyCols && jyCols < 9) {
infoTable = document.createTable(2, jyCols);
xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER);
xwpfHelperTable.mergeCellsHorizontal(infoTable, 0, 5, jyCols - 1);
xwpfHelperTable.mergeCellsHorizontal(infoTable, 1, 1, jyCols - 1);
} else {
infoTable = document.createTable(2, jyCols);
xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER);
xwpfHelperTable.mergeCellsHorizontal(infoTable, 0, 1, 2);
xwpfHelperTable.mergeCellsHorizontal(infoTable, 0, 4, 5);
xwpfHelperTable.mergeCellsHorizontal(infoTable, 0, 7, jyCols - 1);
xwpfHelperTable.mergeCellsHorizontal(infoTable, 1, 1, jyCols - 1);
}
// xwpfHelperTable.mergeCellsVertically(infoTable, 0, 3, 9);
// 设置表格样式
List<XWPFTableRow> rowList = infoTable.getRows();
for (int i = 0; i < rowList.size(); i++) {
XWPFTableRow infoTableRow = rowList.get(i);
List<XWPFTableCell> cellList = infoTableRow.getTableCells();
for (int j = 0; j < cellList.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphs().get(0);
cellParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun cellParagraphRun = cellParagraph.createRun();
cellParagraphRun.setFontSize(12);
}
}
xwpfHelperTable.setTableHeight(infoTable, 560, STVerticalJc.CENTER);
return infoTable;
}
/**
* 设置表格 意见表2
*
* @param document
* @param rows
* @param cols
* @Author Huangxiaocong 2018年12月16日
*/
public XWPFTable createTableParagraphJY2(XWPFDocument document, List<List<String>> tableList) {
int rows = tableList.size();
int cols = tableList.get(0).size();
XWPFTable infoTable = document.createTable(10, cols);
xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER);
// 合并表格
List<XWPFTableRow> rowList = infoTable.getRows();
for (int i = 0; i < rowList.size(); i++) {
XWPFTableRow infoTableRow = rowList.get(i);
List<XWPFTableCell> cellList = infoTableRow.getTableCells();
for (int j = 0; j < cellList.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphs().get(0);
cellParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun cellParagraphRun = cellParagraph.createRun();
cellParagraphRun.setFontSize(12);
}
}
xwpfHelperTable.setTableHeight(infoTable, 560, STVerticalJc.CENTER);
return infoTable;
}
/**
* 设置页眉方法
*
* @param document
* 文档对象
* @param
* @param fontSize
*/
private void setXWPFRunStyle(XWPFDocument document, String docHead) throws Exception {
CTP ctp = CTP.Factory.newInstance();
XWPFParagraph paragraph2 = new XWPFParagraph(ctp, document);// 段落对象
paragraph2.setFontAlignment(3);
ctp.addNewR().addNewT().setStringValue(docHead);// 设置页眉参数
ctp.addNewR().addNewT().setSpace(SpaceAttribute.Space.PRESERVE);
CTSectPr sectPr = document.getDocument().getBody().isSetSectPr() ? document.getDocument().getBody().getSectPr()
: document.getDocument().getBody().addNewSectPr();
XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(document, sectPr);
XWPFHeader header = policy.createHeader(STHdrFtr.DEFAULT, new XWPFParagraph[] { paragraph2 });
header.setXWPFDocument(document);
}
/**
* 设置附录
*
* @param document
* 文档对象
* @param
* @param fontSize
*/
private void setDocumentFL(XWPFParagraph paragraph, String flString) throws Exception {
paragraph.setAlignment(ParagraphAlignment.LEFT);// 样式居中
XWPFRun runTitle = paragraph.createRun(); // 创建文本对象
// titleFun.setText(titleName); //设置标题的名字
runTitle.setBold(true); // 加粗
runTitle.setColor("000000");// 设置颜色
runTitle.setFontSize(10); // 字体大小
runTitle.setText(flString);
}
/**
* 结尾
*
* @param paragraph
* @throws Exception
*/
private void setDocumentJW(XWPFParagraph paragraph, int i,String date) throws Exception {
paragraph.setAlignment(ParagraphAlignment.CENTER);// 样式居中
paragraph.setSpacingAfter(1);
XWPFRun runTitle = paragraph.createRun(); // 创建文本对象
// titleFun.setText(titleName); //设置标题的名字
runTitle.setBold(true); // 加粗
for (int j = 0; j < i; j++) {
runTitle.addCarriageReturn();
}
runTitle.setText(" 这里是个结尾 ");
runTitle.addCarriageReturn();
if(date!=null) {
runTitle.setText(date);
}else {
runTitle.setText(" 年 月 日");
}
}
/**
* 封面 第一页
*
* @param document
* 文档对象
* @param
* @param fontSize
*/
private void setDocumentFM(XWPFParagraph paragraph, List<String> dataList) throws Exception {
paragraph.setAlignment(ParagraphAlignment.CENTER);// 样式居中
XWPFRun run = paragraph.createRun(); // 创建文本对象
XWPFRun runTitle = paragraph.createRun(); // 创建文本对象
// titleFun.setText(titleName); //设置标题的名字
runTitle.setBold(true); // 加粗
runTitle.setColor("000000");// 设置颜色
runTitle.setFontSize(25); // 字体大小
runTitle.setText("大号标题");
// 封面字段 前后加回车换行
XWPFRun runFM = paragraph.createRun();
runFM.setFontSize(20);
runFM.addCarriageReturn();
runFM.addCarriageReturn();
runFM.addCarriageReturn();
//计算加空格数量
int returnNumber = 12/dataList.size();
for (int i = 0; i < dataList.size(); i++) {
runFM.setText(dataList.get(i));
for(int j = 0;j<returnNumber;j++) {
runFM.addCarriageReturn();
}
//runFM.addCarriageReturn();
}
}
/**
* 评审人员名单
*
* @param document
* 文档对象
* @param
* @param fontSize
*/
private void setDocumentRY(XWPFParagraph paragraph) throws Exception {
paragraph.setAlignment(ParagraphAlignment.LEFT);// 样式居中
XWPFRun run = paragraph.createRun(); // 创建文本对象
run.setText("人员名单");
run.addCarriageReturn();
}
/**
* 评审意见跟踪检查表
*
* @param document
* 文档对象
* @param
* @param fontSize
*/
private void setDocumentJY(XWPFParagraph paragraph) throws Exception {
paragraph.setAlignment(ParagraphAlignment.CENTER);// 样式居中
XWPFRun run = paragraph.createRun(); // 创建文本对象
run.setBold(true); // 加粗
run.setText("检查表");
run.addCarriageReturn();
}
/**
* 编号
*
* @param document
* 文档对象
* @param
* @param fontSize
*/
private void setDocumentBH(XWPFParagraph paragraph) throws Exception {
paragraph.setAlignment(ParagraphAlignment.RIGHT);// 样式居中
XWPFRun run = paragraph.createRun(); // 创建文本对象
run.setText("编号:___________");
run.addCarriageReturn();
}
/**
* 意见结尾
*
* @param document
* 文档对象
* @param
* @param fontSize
*/
private void setDocumentJYW(XWPFParagraph paragraph) throws Exception {
paragraph.setAlignment(ParagraphAlignment.CENTER);// 样式居中
XWPFRun run = paragraph.createRun(); // 创建文本对象
run.addCarriageReturn();
run.addCarriageReturn();
run.setText("人:_________ PQA:________ 代表_______ ________年_____月_____日");
run.addCarriageReturn();
}
/**
*
* @param docHead
* 页眉
* @param dataList
* 封面LIST
* @param tableDataZT
* 主体表
* @param listRY
* 人员表
* @param listJY
* 建议表头
* @param listJY2
* 建议字段
* @param document
* @param savePath
* @throws Exception
*/
@SuppressWarnings("unchecked")
public void exportCheckWord(String docHead, String date,String zjsi,List<String> dataList, List<List<String>> tableDataZT,
List<List<String>> listRY, List<List<String>> listJY, int jyClos, List<List<String>> listJY2,
XWPFDocument document) throws Exception {
// 设置页眉
setXWPFRunStyle(document, docHead);
// 附录
XWPFParagraph paragraphFl = document.createParagraph();
setDocumentFL(paragraphFl, "左边一号");
// 标题 封面
XWPFParagraph paragraph = document.createParagraph();
setDocumentFM(paragraph, dataList);
// 结尾 个回车
int i = 5;
XWPFParagraph paragraphJW = document.createParagraph();
setDocumentJW(paragraphJW, i,date);
// 主题表
XWPFParagraph paragraphZT = document.createParagraph();
paragraphZT.setPageBreak(true);//换页
XWPFTable table1 = createTableParagraph(document, tableDataZT);
fillTableData(table1, tableDataZT,zjsi);
// 人员表
XWPFParagraph paragraphRY = document.createParagraph();
paragraphRY.setPageBreak(true);
setDocumentRY(paragraphRY);
XWPFTable table2 = createTableParagraphRY(document, listRY);
fillTableDataRY(table2, listRY);
// 意见表
XWPFParagraph paragraphJY = document.createParagraph();
paragraphJY.setPageBreak(true);
setDocumentFL(paragraphJY, "左边二号");
XWPFParagraph paragraphJY2 = document.createParagraph();
setDocumentJY(paragraphJY2);
XWPFParagraph paragraphJY3 = document.createParagraph();
setDocumentBH(paragraphJY3);
XWPFTable table3 = createTableParagraphJY(document, listJY, jyClos);
fillTableDataJY(table3, listJY);
XWPFTable table4 = createTableParagraphJY2(document, listJY2);
fillTableDataJY(table4, listJY2);
// 意见结尾
XWPFParagraph paragraphJYW = document.createParagraph();
setDocumentJYW(paragraphJYW);
// xwpfHelper.saveDocument(document, savePath);
}
/**
* 往表格中填充数据 主题表
*
* @param table
* @param tableData
* @Author 2018年12月16日
*/
public void fillTableData(XWPFTable table, List<List<String>> tableData,String zjsi) {
List<XWPFTableRow> rowList = table.getRows();
for (int i = 0; i < tableData.size(); i++) {
List<String> list = tableData.get(i);
List<XWPFTableCell> cellList = rowList.get(i).getTableCells();
for (int j = 0; j < list.size(); j++) {
// XWPFRun cellParagraphRun = paragraphTable1.createRun();
XWPFParagraph cellParagraph = cellList.get(j).getParagraphs().get(0);
XWPFRun cellParagraphRun = cellParagraph.getRuns().get(0);
String tt = list.get(j);
if (tt.equals("空格")) {//没找的空格占位的方法 需要占位的时候加白色字占位
cellParagraphRun.setColor("ffffff");
}
cellParagraphRun.setText(String.valueOf(list.get(j)));
if (i > 0) { //签名
cellParagraphRun.addBreak();
cellParagraphRun.addBreak();
cellParagraphRun.addBreak();
if(i==(tableData.size()-1)) {
XWPFTableCell xwpfTableCell = cellList.get(j);
XWPFParagraph addParagraph = xwpfTableCell.addParagraph();
addParagraph.setAlignment(ParagraphAlignment.RIGHT);// 样式靠右
XWPFRun createRun = addParagraph.createRun();
createRun.setText(zjsi);
}
}
}
}
}
/**
* 往表格中填充数据人员表
*
* @param table
* @param tableData
* @Author Huangxiaocong 2018年12月16日
*/
public void fillTableDataRY(XWPFTable table, List<List<String>> tableData) {
List<XWPFTableRow> rowList = table.getRows();
for (int i = 0; i < tableData.size(); i++) {
List<String> list = tableData.get(i);
List<XWPFTableCell> cellList = rowList.get(i).getTableCells();
if (i > 0) {
for (int j = 0; j < list.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphs().get(0);
XWPFRun cellParagraphRun = cellParagraph.getRuns().get(0);
if (list.get(0).equals("")) {
cellParagraphRun.setText(String.valueOf(list.get(j)));
} else {
if (j > 0) {
cellParagraphRun.setText(String.valueOf(list.get(j)));
} else {
String string = list.get(0);
String[] split = string.split(",");
cellParagraphRun.setText(split[0]);
}
}
}
} else {
for (int j = 0; j < list.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphs().get(0);
XWPFRun cellParagraphRun = cellParagraph.getRuns().get(0);
cellParagraphRun.setText(String.valueOf(list.get(j)));
}
}
}
}
/**
* 往表格中填充数据 意见表
*
* @param table
* @param tableData
* @Author Huangxiaocong 2018年12月16日
*/
public void fillTableDataJY(XWPFTable table, List<List<String>> tableData) {
List<XWPFTableRow> rowList = table.getRows();
for (int i = 0; i < tableData.size(); i++) {
List<String> list = tableData.get(i);
List<XWPFTableCell> cellList = rowList.get(i).getTableCells();
for (int j = 0; j < list.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphs().get(0);
XWPFRun cellParagraphRun = cellParagraph.getRuns().get(0);
cellParagraphRun.setText(String.valueOf(list.get(j)));
}
}
}
}
返回前端方法
ExportWord ew = new ExportWord();
XWPFDocument document = ew.createXWPFDocument();
String zjsi = "签名";
ew.exportCheckWord(docHead, null, zjsi, listFMString, listZT, listRY, listJY1, jyCols, listJY2, document);
//
//Map<String, Object> map = new HashMap<String, Object>();
// 二进制返回前台
response.setHeader("content-disposition",
"attachment;filename=" + URLEncoder.encode(docName, "utf-8") + ".docx");
OutputStream out = response.getOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.write(baos);
byte[] xlsBytes = baos.toByteArray();
out.write(xlsBytes);
out.close();
传参数list示例 大的List是列 里面的list是行里面参数
List<List<String>> listZT = new ArrayList<List<String>>();
List<String> tempList = new ArrayList<String>();
tempList.add("产品名称");
tempList.add("空格");
tempList.add("产品代号");
tempList.add("空格");
listZT.add(tempList);