public static void exportToWord(List<EntityItem> records, String outputPath) throws Exception {
try (XWPFDocument doc = new XWPFDocument()) {
// ========== 1. 页面设置(紧凑页边距) ==========
CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
CTPageSz pageSize = sectPr.addNewPgSz();
pageSize.setOrient(STPageOrientation.LANDSCAPE);
pageSize.setW(BigInteger.valueOf(16840)); // A4横向宽度
pageSize.setH(BigInteger.valueOf(11900)); // A4横向高度
// 紧凑页边距(单位:twips,1cm≈567twips)
CTPageMar pageMar = sectPr.addNewPgMar();
pageMar.setLeft(BigInteger.valueOf(390)); // 1.5cm (原1440=2.54cm)
pageMar.setRight(BigInteger.valueOf(390)); // 1.5cm
pageMar.setTop(BigInteger.valueOf(900)); // 2cm (原1800=3.17cm)
pageMar.setBottom(BigInteger.valueOf(900));// 2cm
pageMar.setFooter(BigInteger.valueOf(900)); // 页脚1.59cm
// ========== 2. 创建表格 ==========
XWPFTable table = doc.createTable();
table.setWidth("100%");
// 列宽设置(单位:twips)
int[] columnWidths = {500, 800, 1200, 5000, 5000};
CTTbl cttbl = table.getCTTbl();
CTTblGrid tblGrid = cttbl.addNewTblGrid();
for (int width : columnWidths) {
tblGrid.addNewGridCol().setW(BigInteger.valueOf(width));
}
// ========== 3. 表头样式(水平居中+加粗大字) ==========
XWPFTableRow headerRow = table.getRow(0);
for (int i = 0; i < columnWidths.length; i++) {
XWPFTableCell cell = headerRow.getCell(i);
if (cell == null) cell = headerRow.createCell();
// 设置列宽
cell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(columnWidths[i]));
// 创建水平居中段落
cell.removeParagraph(0);
XWPFParagraph para = cell.addParagraph();
para.setAlignment(ParagraphAlignment.CENTER); // 水平居中
// 设置标题样式
XWPFRun run = para.createRun();
run.setBold(true);
run.setFontSize(12); // 标题行字体放大
run.setText(getHeaderText(i));
run.setColor("000000");
}
// ========== 4. 数据行样式(水平居中) ==========
int num = 0;
for (EntityItem record : records) {
XWPFTableRow row = table.createRow();
row.setCantSplitRow(true);
// 序号列(水平居中)
createCenteredCell(row, 0, String.valueOf(++num));
// 工装编号列(水平居中)
createCenteredCell(row, 1, record.getToolNumber());
// 资产名称列(水平居中)
createCenteredCell(row, 2, record.getToolName());
// 图片列1(左对齐)
XWPFTableCell imageCell = row.getCell(3);
imageCell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(columnWidths[3]));
addImagesToCell(imageCell, record.getPropertyUri(), "D:\\imageFile\\");
// 图片列2(左对齐)
XWPFTableCell nameplateCell = row.getCell(4);
nameplateCell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(columnWidths[4]));
addImagesToCell(nameplateCell, record.getNameplateUri(), "D:\\imageFile\\");
}
// ========== 5. 添加页码 ==========
addPageNumbers(doc);
// ========== 6. 保存文档 ==========
try (FileOutputStream out = new FileOutputStream(outputPath)) {
doc.write(out);
}
}
}
// 辅助方法:创建水平居中单元格
private static void createCenteredCell(XWPFTableRow row, int pos, String text) {
XWPFTableCell cell = row.getCell(pos);
if (cell == null) cell = row.createCell();
cell.removeParagraph(0);
XWPFParagraph para = cell.addParagraph();
para.setAlignment(ParagraphAlignment.CENTER); // 水平居中
XWPFRun run = para.createRun();
run.setText(text);
}
// 辅助方法:添加图片到单元格(左对齐)
private static void addImagesToCell(XWPFTableCell cell, List<String> imagePaths, String basePath) throws Exception {
XWPFParagraph para = cell.addParagraph();
para.setAlignment(ParagraphAlignment.LEFT); // 图片左对齐
XWPFRun run = para.createRun();
for (int i = 0; i < imagePaths.size(); i++) {
try (java.io.InputStream is = new java.io.FileInputStream(basePath + imagePaths.get(i))) {
run.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, imagePaths.get(i),
Units.toEMU(100), Units.toEMU(100));
// 每3张图片换行
if ((i + 1) % 3 == 0 && i != imagePaths.size() - 1) {
run.addBreak();
}
}
}
}
// 表头文本
private static String getHeaderText(int colIndex) {
String[] headers = {"序号", "工装编号", "资产名称", "关联图片", "铭牌"};
return headers[colIndex];
}
// 页码添加
private static void addPageNumbers(XWPFDocument doc) {
XWPFFooter footer = doc.createFooter(HeaderFooterType.DEFAULT);
XWPFParagraph para = footer.createParagraph();
para.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = para.createRun();
run.getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
run.getCTR().addNewInstrText().setStringValue("PAGE");
run.getCTR().addNewFldChar().setFldCharType(STFldCharType.END);
run.setText(" / ");
run.getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
run.getCTR().addNewInstrText().setStringValue("NUMPAGES");
run.getCTR().addNewFldChar().setFldCharType(STFldCharType.END);
}根据代码修改为每页5行数据包含表头,一个图片单元格横向最多放3张图片多了之后换行,如果图片换行也占用一行总行数,如果图片换行后不在当前页整条数据都移动至下一页