1:需要的jar包
百度云: https://pan.baidu.com/s/1TP9YWhTQu8QHpB41AU3I5Q 提取码: ymtj
maven:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.3</version>
</dependency>
2:做法 创建一个Java工程-------引入夹包------写个测试类测试,如下图大概结构
3:类代码写法,直接创建一个类,把代码全部粘过去,运行main方法,看D盘生成的文件
//*********************************类代码写法开始*************************************
package com;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
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.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
/**
* 一些其他的网站写法
* https://elim.iteye.com/blog/2049110
* https://www.cnblogs.com/unruly/archive/2017/09/06/7483858.html
* https://www.cnblogs.com/zyc-blogs/p/10558859.html
* https://blog.csdn.net/ztt_1119/article/details/69390807
* http://poi.apache.org/apidocs/dev/org/apache/poi/xwpf/usermodel/XWPFTable.html
* https://blog.csdn.net/ztt_1119/article/details/69390807
* https://www.cnblogs.com/sun-flower1314/p/10128796.html
* https://wenku.baidu.com/view/2507cb89905f804d2b160b4e767f5acfa0c78336.html
* https://53873039oycg.iteye.com/blog/2157923
* https://www.cnblogs.com/dayuruozhi/p/6490868.html
*/
public class TestWord {
//初始化XWPFDocument
public static XWPFDocument initDoc(List<Map<String,Object>> list){
XWPFDocument document= new XWPFDocument();
//============添加标题====================
XWPFParagraph titleParagraph = document.createParagraph();
//设置段落居中
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleParagraphRun = titleParagraph.createRun();
titleParagraphRun.setText("测试使用poi导出word");
titleParagraphRun.setBold(true);//加粗
titleParagraphRun.setFontSize(20);//字体大小
//====================设置段落======================
XWPFParagraph firstParagraph = document.createParagraph();
firstParagraph.setAlignment(ParagraphAlignment.RIGHT);//设置段落内容靠右
firstParagraph.setIndentationRight(300);//末尾缩进300
XWPFRun run = firstParagraph.createRun();
run.setText("测试段落 样式设置");
run.setBold(true); //加粗
run.setFontSize(14);//字体大小
//==============添加表格数据===========
//数据表格
XWPFTable ComTable = document.createTable();//默认创建一个一行一列的表格
//列宽自动分割
CTTblWidth comTableWidth = ComTable.getCTTbl().addNewTblPr().addNewTblW();
comTableWidth.setType(STTblWidth.DXA);//每列自动扩展根据内容
//表格表头行
XWPFTableRow titleRow = ComTable.getRow(0);//创建的的一行一列的表格,获取第一行
titleRow.setHeight(550);//设置当前行行高
titleStyle(titleRow);//设置表头行样式和内容
//将数据封装到表格中
for(Map<String,Object> m:list){
//=============创建表格表头行下第一行----合并单位名称======================
XWPFTableRow DWMCRow = ComTable.createRow();//创建表头行下新的一行,列数是按照表头行的列数创建的
DWMCRow.setHeight(600);//设置行高
//获取当前行的列数,原理第一行有几列,下面创建的新行就有几列,如果创建表格时指定了,就按指定的数创建多少列
List<XWPFTableCell> DWMCCellList = DWMCRow.getTableCells();
for (int i = 0; i < DWMCCellList.size(); i++) {//经过这个循环后就将这一行的所有列合并成一列了
//对单元格进行合并的时候,要标志单元格是否为起点,或者是否为继续合并
if (i == 0)
DWMCCellList.get(i).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);//这是起点
else
DWMCCellList.get(i).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);//继续合并
}
XWPFTableCell DWMCCell = DWMCCellList.get(0);//当前行合并成一列了,获取这一列
TitleCelldata(DWMCCell,m.get("dwmc")==null?"无":m.get("dwmc").toString());//给列添加样式和数据
//=================================遍历具体的数据===============================
List<Map<String,Object>> list1 = (List<Map<String,Object>>)m.get("data");
int i=0;
for(Map<String,Object> dm:list1){
XWPFTableRow dataRow = ComTable.createRow();//创建一个新的行
dataRow.setHeight(500);//设置行高
List<XWPFTableCell> DataCellList = dataRow.getTableCells();//获取创建行的所有的列
XWPFTableCell tc0 = DataCellList.get(0);//获取创建行的第一列
CelldataCss(tc0,"500");//给第一列序号添加样式
tc0.setText(++i+"");//给第一列添加值
for(int ci=1;ci<DataCellList.size();ci++){//循环给剩下的列赋值
XWPFTableCell tc = DataCellList.get(ci);
CelldataCss(tc,"1600");//给列添加样式
CellData(dm, tc, ci);//填充数据
}
}
}
return document;
}
//设置表头行样式和内容
public static void titleStyle(XWPFTableRow titleRow){
XWPFTableCell xhCell = titleRow.getCell(0);//创建的表格没有指定几行几列,就默认是一行一列,这里获取创建的第一列
xhCell.setText("");
CelldataCss(xhCell,"500");
XWPFTableCell bmCell =titleRow.addNewTableCell();//在当前行继续创建新列
TitleCelldata(bmCell,"部门");
XWPFTableCell xmCell =titleRow.addNewTableCell();
TitleCelldata(xmCell,"姓名");
XWPFTableCell zwCell =titleRow.addNewTableCell();
TitleCelldata(zwCell,"职务");
XWPFTableCell bgdhCell =titleRow.addNewTableCell();
TitleCelldata(bgdhCell,"办公电话");
XWPFTableCell sjhmCell =titleRow.addNewTableCell();
TitleCelldata(sjhmCell,"手机号码");
XWPFTableCell yxCell =titleRow.addNewTableCell();
TitleCelldata(yxCell,"邮箱");
}
//设置数据列样式
public static void CelldataCss(XWPFTableCell cell,String width){
/** 设置水平居中 */
CTTc cttc = cell.getCTTc();
CTTcPr ctPr = cttc.addNewTcPr();
ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);//上下居中
cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);//左右居中
CTTblWidth tblWidth = ctPr.isSetTcW() ? ctPr.getTcW() : ctPr.addNewTcW();
tblWidth.setW(new BigInteger(width));//设置列宽度
tblWidth.setType(STTblWidth.DXA);
}
//设置表头和单位信息样式
public static void TitleCelldata(XWPFTableCell cell,String txt){
//给当前列中添加段落,就是给列添加内容
XWPFParagraph p = cell.getParagraphs().get(0);
XWPFRun headRun0 = p.createRun();
headRun0.setText(txt);//设置内容
headRun0.setFontSize(12);//设置大小
headRun0.setBold(true);//是否粗体
//给列中的内容设置样式
CTTc cttc = cell.getCTTc();
CTTcPr ctPr = cttc.addNewTcPr();
ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);//上下居中
cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);//左右居中
}
//将数据赋值到每一列上
public static void CellData(Map<String,Object> m,XWPFTableCell cell,Integer ic){
switch(ic){
case 1:
cell.setText(m.get("bm")==null?"无":m.get("bm").toString());
break;
case 2:
cell.setText(m.get("mc")==null?"无":m.get("mc").toString());
break;
case 3:
cell.setText(m.get("zw")==null?"无":m.get("zw").toString());
break;
case 4:
cell.setText(m.get("bgdh")==null?"无":m.get("bgdh").toString());
break;
case 5:
cell.setText(m.get("sjhm")==null?"无":m.get("sjhm").toString());
break;
case 6:
cell.setText(m.get("yx")==null?"无":m.get("yx").toString());
break;
}
}
//手动构造数据
public static List<Map<String,Object>> data(){
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
Map<String,Object> m1 = new HashMap<String,Object>();
m1.put("dwmc", "测试部门1");
List<Map<String,Object>> list1 = new ArrayList<Map<String,Object>>();
for(int i=0;i<5;i++){
Map<String,Object> d1 = new HashMap<String,Object>();
d1.put("bm", "部门"+i);//部门
d1.put("mc", "名称"+i);//名称
d1.put("zw", "职务"+i);//职务
d1.put("bgdh", "办公电话"+i);//办公电话
d1.put("sjhm", "手机号码"+i);//手机号码
d1.put("yx", "邮箱"+i);//邮箱
d1.put("xh", i+1);//序号
list1.add(d1);
}
m1.put("data", list1);
Map<String,Object> m2 = new HashMap<String,Object>();
m2.put("dwmc", "测试部门2");
List<Map<String,Object>> list2 = new ArrayList<Map<String,Object>>();
for(int i=0;i<3;i++){
Map<String,Object> d1 = new HashMap<String,Object>();
d1.put("bm", "部门"+i);//部门
d1.put("mc", "名称"+i);//名称
d1.put("zw", "职务"+i);//职务
d1.put("bgdh", "办公电话"+i);//办公电话
d1.put("sjhm", "手机号码"+i);//手机号码
d1.put("yx", "邮箱"+i);//邮箱
d1.put("xh", i+1);//序号
list2.add(d1);
}
m2.put("data", list2);
Map<String,Object> m3 = new HashMap<String,Object>();
m3.put("dwmc", "测试部门3");
List<Map<String,Object>> list3 = new ArrayList<Map<String,Object>>();
for(int i=0;i<2;i++){
Map<String,Object> d1 = new HashMap<String,Object>();
d1.put("bm", "部门"+i);//部门
d1.put("mc", "名称"+i);//名称
d1.put("zw", "职务"+i);//职务
d1.put("bgdh", "办公电话"+i);//办公电话
d1.put("sjhm", "手机号码"+i);//手机号码
d1.put("yx", "邮箱"+i);//邮箱
d1.put("xh", i+1);//序号
list3.add(d1);
}
m3.put("data", list3);
list.add(m1);
list.add(m2);
list.add(m3);
return list;
}
public static void main(String[] args) throws Exception {
XWPFDocument document= initDoc(data());
FileOutputStream out = new FileOutputStream("d:\\部门通讯录.docx");
document.write(out);
out.close();
System.out.println("导出成功!!!!!!!!");
}
}
//*********************************类代码写法结束*************************************
4:生成的效果
5:在web项目中controller中的大概写法,这样前端直接调用这个方法,就会在页面上直接下载了
//**********************************开始****************************************
public String exportWord(HttpServletRequest request, HttpServletResponse response) {
List<Map<String,Object>> dataList = DjOrgTxlDwryServiceImpl.exportWord();//获取数据,一般是从库里查询的数据,这里可以改成自己造的数据
if(!ObjectUtils.isEmpty(dataList)){//判断数据不为null,并且不为空
try {
XWPFDocument document= WordExport.initDoc(dataList);
String filename="部门通讯录";
response.setHeader("Content-Disposition","attachment;filename="+new String(filename.getBytes(), "iso8859-1")+".docx");
OutputStream out = response.getOutputStream();
document.write(out);
out.close();
return null;
} catch (IOException e) {
return "导出数据异常!!!!!";
}
}else{
return "查询数据为空,没有要导出的数据";
}
}
//**********************************结束***************************************