之前弄过使用easyPOI导出excel文件,现在差不多同样的需求,但是导出的文件换成了word文档,虽然里面还是表格样式,但是文件格式不同了,话不多说,直接上代码:
用了两种方式,个人感觉第二个更好一点,直接获取对象的数据,不用单独拿出来,不过就是需要模板,而第一个就完全使用代码即可
1.直接写代码,不需要模板:
private int exportWord(){
try {
//tab的格式是:{tableArr:表头集合},表头集合:[{id:id,value:value},{}....]
Map<String,Object> tab = new HashMap<>();
//获取tab里的表头集合
List<Map<String,String>> table = (List<Map<String,String>>)tab.get("tableArr");
//创建一个集合用来单独管理表头集合里的表头value
List<String> head = new ArrayList<>();
for(Map<String,String> map:table){
head.add(map.get("value"));
}
/**
* 加一些数据
**/
List<Object> data = new ArrayList<>();
for(int i = 0;i<6;i++){
data.add(i);
}
List<Object> data1 = new ArrayList<>();
for(int i = 6;i<12;i++){
data1.add(i);
}
List<Object> data2 = new ArrayList<>();
for(int i = 6;i<12;i++){
data2.add(i);
}
List<Object> data11 = new ArrayList<>();
data11.add(0);
data11.add(1);
data.add(6,data11);
data1.add(6,data11);
data2.add(6,data11);
//创建一个集合用来管理word的表里的数据
List<List<Object>> dataList = new ArrayList<>();
dataList.add(data);
dataList.add(data1);
dataList.add(data2);
dataList.add(data);
dataList.add(data);
//创建文档对象
XWPFDocument document= new XWPFDocument();
//将创建的文档对象写入系统文件中
FileOutputStream out = new FileOutputStream(new File("C:\\seaLoong.docx"));
//给创建好的文档对象添加文本行
XWPFParagraph titleParagraph = document.createParagraph();
//添加其他行
XWPFParagraph timeParagraph = document.createParagraph();
//设置段落居中
titleParagraph.setAlignment(ParagraphAlignment.CENTER);
//设置段落靠左
timeParagraph.setAlignment(ParagraphAlignment.LEFT);
//XWPFRun是XWPFDocument中的一段文本对象
XWPFRun titleParagraphRun = titleParagraph.createRun();
XWPFRun titleParagraphRunTwo = timeParagraph.createRun();
//设置文本行当标题
titleParagraphRun.setText("标题名");
//标题颜色
titleParagraphRun.setColor("000000");
//标题字体大小
titleParagraphRun.setFontSize(20);
titleParagraphRunTwo.setText("采样日期:"+"2020-12-31");
//给创建好的文档对象添加表格(基本信息表格)
XWPFTable infoTable = document.createTable();
//文档中表格下方添加一个文本行(按顺序来的:文本行,表格,文本行)
XWPFParagraph detailParagraph = document.createParagraph();
detailParagraph.setAlignment(ParagraphAlignment.LEFT);
XWPFRun titleParagraphRunThree = detailParagraph.createRun();
titleParagraphRunThree.setText("人员签名:"+"非诚勿扰");
//列宽自动分割
CTTblWidth infoTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW();
infoTableWidth.setType(STTblWidth.DXA);
infoTableWidth.setW(BigInteger.valueOf(9072));
//表格第一行
XWPFTableRow infoTableRowOne = infoTable.getRow(0);
//先获取第一个表头传给表格的第一行第一个(好像只能用getCell(),直接遍历会报错,不知道为啥)
infoTableRowOne.getCell(0).setText(head.get(0));
//设置表格中的文本居中
infoTableRowOne.getCell(0).getParagraphArray(0).setAlignment(ParagraphAlignment.CENTER);
for(int i = 1;head.size()>i;i++){
infoTableRowOne.addNewTableCell().setText(head.get(i));
infoTableRowOne.getCell(i).getParagraphArray(0).setAlignment(ParagraphAlignment.CENTER);
}
int num = 0;
//遍历,因为不确定是不是一个东西会有多种解释所以需要根据里面的集合来遍历创建相同行但不同集合子值的行,后期直接合并相同的单元格即可
for(List<Object> info:dataList){
for (int j=0; data11.size()>j;j++){
XWPFTableRow infoTableRow = infoTable.createRow();
for(int i = 0;info.size()>i;i++){
if(info.get(i)!=null){
if(i==6){
infoTableRow.getCell(i).setText(data11.get(j).toString());
infoTableRow.getCell(i).getParagraphArray(0).setAlignment(ParagraphAlignment.CENTER);
}else {
infoTableRow.getCell(i).setText(info.get(i).toString());
infoTableRow.getCell(i).getParagraphArray(0).setAlignment(ParagraphAlignment.CENTER);
}
}else {
infoTableRow.addNewTableCell().setText("");
}
}
}
}
//根据data11有多少数据来判断合并单元格
for (int j=0; dataList.size()>j;j++) {
for (int i = 0; 6 > i; i++) {
int fromRow = num + 1;
int toRow = num + data11.size();
//一个合并单元格的方法
mergeCellsVertically(infoTable, i, fromRow, toRow);
}
num = num + data11.size();
}
//略
document.write(out);
out.close();
return 1;
} catch (IOException e) {
e.printStackTrace();
return 0;
}
}
2.需要模板:
2.1 代码
private int exportWord(){
try{
//模板地址
String templateFilePath = "D:/OtherACC/";
//生成文件的保存地址
String destFilePath = "D:/OtherACC/Aaa/";
//创建Map将表中数据填入
Map<String, Object> datas = new HashMap<String, Object>();
//添加一些数据
Student student1 = new Student();
student1.setPointName("12");
student1.setWeatherStr("1");
student1.setWaterColorStr("张三");
student1.setSmellStr("男");
student1.setOilSlickStr("男");
student1.setSeaStatusStr("男");
Student student2 = new Student();
student2.setPointName("12");
student2.setWeatherStr("1");
student2.setWaterColorStr("张三");
student2.setSmellStr("男");
student2.setOilSlickStr("男");
student2.setSeaStatusStr("男");
List<String> boys = new ArrayList<>();
String a = "aaa";
String b = "bbb";
boys.add(a);
boys.add(b);
student1.setItemNames(boys);
List<Student> studentList = new ArrayList<>();
studentList.add(student2);
studentList.add(student1);
studentList.add(student2);
studentList.add(student1);
studentList.add(student1);
List<Student> students = new ArrayList<>();
// 遍历集合,判断itemName中是否是多条数据
for(Student vo:studentList){
List<String> itemNames = vo.getItemNames();
如果itemName是多条数据就循环多次添加其他字段
if(itemNames!=null){
for (String itemName:vo.getItemNames()) {
Student stu = new Student();
stu.setPointName(vo.getPointName());
stu.setWeatherStr(vo.getWeatherStr());
stu.setWaterColorStr(vo.getWaterColorStr());
stu.setSmellStr(vo.getSmellStr());
stu.setOilSlickStr(vo.getOilSlickStr());
stu.setSeaStatusStr(vo.getSeaStatusStr());
stu.setSampleCode(vo.getSampleCode());
stu.setNowItems(vo.getNowItems());
stu.setSaveMethodStr(vo.getSaveMethodStr());
stu.setItemName(itemName);
students.add(stu);
}
}else {
//如果不是就将原本的数据添加进集合即可
students.add(vo);
}
}
datas.put("lists",students);
datas.put("sampleDate","2023-12-31");
datas.put("sampleUserAutograph","采样人员签名");
datas.put("checkUserAutograph","审核人员签名");
// 插件列表,可以去官网查看,有列循环,还有行循环,这里是行循环实例
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
//这里可以指定一个config类,用来指定一些规则,也可以改变模板中{{}}的这种格式
Configure config = Configure.builder()
.bind("lists", policy).build();
// 获取模版,将数据写入
XWPFTemplate compile = XWPFTemplate.compile(templateFilePath + "采样单模板.docx",config);
compile.render(datas);
//获取表格对象(重点,这是将模板转换成表格对象的方法,只有切换成了表格对象才能进行合并单元格的操作)
XWPFTable table = compile.getXWPFDocument().getTableArray(0);
int num = 0;
for (Student vo:studentList) {
int nameSize = 0;
for (int i = 0; 8 > i; i++) {
List<String> itemNames = vo.getItemNames();
if(itemNames==null){
nameSize = 1;
}else {
nameSize = itemNames.size();
}
int fromRow = num + 1;
int toRow = num + nameSize;
mergeCellsVertically(table, i, fromRow, toRow);
}
num = num + nameSize;
}
compile.writeToFile(destFilePath+"out_test3.docx");
return 1;
}catch (Exception e){
e.printStackTrace();
return 0;
}
}
2.2模板
{{lists}}是用来接收数据集合的,下面各个表格中的字段都和对象里的字段对应
3.关于合并单元格用的是:
poi word操作之XWPFTable合并单元格_xwpftablecell-CSDN博客
利用模板的主要参考