[原创]排列问题:每行显示4张图片,如果超过4张就换行

博客介绍了 Mod 运算符,包含其描述、语法及相关说明,阐述了 Mod 运算符语法的组成部分。
<table width="100%" border="1" cellspacing="0" cellpadding="1">
<%if rs.eof then
response.write"<tr><td>没有内容</td></tr>"
else%>
<tr>
<%for i=1 to 30
if rs.eof then exit for
response.Write("<td width=120>")
response.Write rs("name")
response.Write("</td>")
if i mod 4=0 then
response.Write("</tr><tr>")
end if
rs.movenext
next
end if%>
</tr>
</table>

主要用到mod函数:
描述
两个数值相除并返回其余数。
语法
result = number1 Mod number2

Mod 运算符的语法有以下部分:

部分描述
result任意数值变量。
number1任意数值表达式。
number2任意数值表达式。
说明
模数或余数。运算符执行 number1 除以 number2 操作(浮点数四舍五入为整数)并只返回余数作为 result。例如,在下面的表达式中, A(为 result)等于 5。
如果任一表达式为 Null,则 result 也为 Null。任一表达式为 Empty 时按 0 来处理。

要解决图片在单元格内直接换行问题(而不是每行显示3图片换行),需要调整图片添加逻辑和单元格布局。以下是修复后的完整代码,确保每单元格内的图片正确排列: ### 修复后的完整代码 ```java import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; import java.math.BigInteger; import java.util.List; public class FixedImageLayoutExport { // 分页配置常量 private static final int DATA_ROWS_PER_PAGE = 4; private static final int MAX_IMAGES_PER_PAGE = 12; private static final int IMAGES_PER_ROW = 3; // 每个单元格内每行显示3图片 private static final int IMAGE_WIDTH_PX = 100; // 图片显示宽度 private static final int IMAGE_HEIGHT_PX = 100; // 图片显示高度 public static void exportToWord(List<EntityItem> records, String outputPath) throws Exception { validateInput(records); try (XWPFDocument doc = new XWPFDocument()) { configurePageSettings(doc); PageContext context = new PageContext(); XWPFTable currentTable = null; for (int idx = 0; idx < records.size(); idx++) { EntityItem record = records.get(idx); int recordImageCount = countRecordImages(record); if (shouldCreateNewPage(context, recordImageCount, idx, records.size())) { addPageBreak(doc, context); } if (context.currentDataRowCount == 0) { currentTable = createNewTable(doc); addTableHeader(currentTable); context.currentDataRowCount++; } XWPFTableRow row = currentTable.createRow(); ensureRowHasCells(row, 5); // 1. 序号列 setCellText(getSafeCell(row, 0), String.valueOf(idx + 1)); // 2. 工装编号列 setCellText(getSafeCell(row, 1), record.getToolNumber()); // 3. 资产名称列 setCellText(getSafeCell(row, 2), record.getToolName()); // 4. 关联图片列(修复重点) XWPFTableCell imageCell = getSafeCell(row, 3); addImagesToCellWithLayout(imageCell, record.getPropertyUri(), "D:\\imageFile\\"); // 5. 铭牌列(修复重点) XWPFTableCell nameplateCell = getSafeCell(row, 4); addImagesToCellWithLayout(nameplateCell, record.getNameplateUri(), "D:\\imageFile\\"); context.update(recordImageCount); if (context.currentDataRowCount >= DATA_ROWS_PER_PAGE - 1 && idx < records.size() - 1) { context.resetForNewPage(); } } addPageNumbers(doc); saveDocument(doc, outputPath); } } // ========== 图片布局修复方法 ========== /** * 在单元格内添加图片并控制布局(每行3图片) */ private static void addImagesToCellWithLayout(XWPFTableCell cell, List<String> imagePaths, String basePath) throws Exception { if (imagePaths == null || imagePaths.isEmpty()) { cell.removeParagraph(0); cell.setText("无图片"); return; } // 清空单元格 cell.removeParagraph(0); // 创建主段落(垂直布局) XWPFParagraph mainPara = cell.addParagraph(); mainPara.setAlignment(ParagraphAlignment.LEFT); mainPara.setSpacingAfter(100); // 段落间间距 int imagesAdded = 0; XWPFRun currentRun = null; for (String path : imagePaths) { try { File imgFile = new File(basePath + path); if (!imgFile.exists()) continue; // 每3图片开始新的一行 if (imagesAdded % IMAGES_PER_ROW == 0) { currentRun = mainPara.createRun(); currentRun.addBreak(); // 换行 } // 添加图片 BufferedImage img = ImageIO.read(imgFile); if (img == null) continue; // 计算缩放比例 double scale = Math.min( IMAGE_WIDTH_PX / (double)img.getWidth(), IMAGE_HEIGHT_PX / (double)img.getHeight() ); int width = (int)(img.getWidth() * scale); int height = (int)(img.getHeight() * scale); try (FileInputStream is = new FileInputStream(imgFile)) { if (currentRun == null) { currentRun = mainPara.createRun(); } currentRun.addPicture(is, getImageType(path), imgFile.getName(), Units.toEMU(width), Units.toEMU(height)); currentRun.addText(" "); // 图片间添加空格 imagesAdded++; } } catch (Exception e) { System.err.println("图片添加失败: " + path); } } } // ========== 其他辅助方法(保持不变)========== private static void ensureRowHasCells(XWPFTableRow row, int cellCount) { while (row.getTableCells().size() < cellCount) { row.createCell(); } } private static XWPFTableCell getSafeCell(XWPFTableRow row, int index) { List<XWPFTableCell> cells = row.getTableCells(); if (index >= 0 && index < cells.size()) { return cells.get(index); } ensureRowHasCells(row, index + 1); return row.getCell(index); } private static void setCellText(XWPFTableCell cell, String text) { if (cell == null) return; cell.removeParagraph(0); XWPFParagraph para = cell.addParagraph(); para.setAlignment(ParagraphAlignment.CENTER); XWPFRun run = para.createRun(); run.setText(text); } // ... 其他方法保持不变 ... } ``` ### 关键修复点 1. **图片布局控制**: - 新增 `addImagesToCellWithLayout()` 方法 - 使用 `XWPFRun` 控制图片排列 - 每3图片后添加换行符 2. **单元格内容管理**: - 先清空单元格原有内容 (`cell.removeParagraph(0)`) - 创建主段落控制整体布局 - 使用单个段落管理多图片 3. **图片间距控制**: - 在图片间添加空格 (`currentRun.addText(" ")`) - 设置段落间距 (`setSpacingAfter`) ### 最佳实践建议 1. **使用表格嵌套**(更精确控制布局): ```java // 在单元格内创建嵌套表格控制图片布局 XWPFTable innerTable = cell.insertNewTbl(new XmlCursor()); XWPFTableRow innerRow = innerTable.createRow(); for (int i = 0; i < 3; i++) { XWPFTableCell imgCell = innerRow.createCell(); if (i < imagePaths.size()) { addSingleImage(imgCell, imagePaths.get(i)); } } ``` 2. **使用绘图工具**(更复杂的布局): ```java // 使用XWPFDrawing控制精确位置 CTDrawing drawing = paragraph.createRun().getCTR().addNewDrawing(); // 设置图片绝对位置... ``` 3. **CSS样式替代方案**(如果使用docx4j): ```java // docx4j支持更精细的布局控制 org.docx4j.wml.P p = factory.createP(); org.docx4j.wml.R r = factory.createR(); org.docx4j.wml.Drawing drawing = factory.createDrawing(); // 设置布局参数... ``` ### 完整示例(嵌套表格方案) ```java private static void addImagesWithNestedTable(XWPFTableCell cell, List<String> imagePaths, String basePath) throws Exception { cell.removeParagraph(0); // 创建嵌套表格(1行×3列) XWPFTable innerTable = cell.insertNewTbl(new XmlCursor()); CTTblWidth innerTableWidth = innerTable.getCTTbl().addNewTblPr().addNewTblW(); innerTableWidth.setW(BigInteger.valueOf(9000)); // 表格宽度 XWPFTableRow innerRow = innerTable.createRow(); // 每列添加一图片 for (int i = 0; i < 3; i++) { XWPFTableCell imgCell = innerRow.createCell(); if (i < imagePaths.size()) { try { addSingleImage(imgCell, basePath + imagePaths.get(i)); } catch (Exception e) { imgCell.setText("图片错误"); } } } } private static void addSingleImage(XWPFTableCell cell, String imagePath) throws Exception { cell.removeParagraph(0); XWPFParagraph para = cell.addParagraph(); para.setAlignment(ParagraphAlignment.CENTER); File imgFile = new File(imagePath); try (FileInputStream is = new FileInputStream(imgFile)) { XWPFRun run = para.createRun(); run.addPicture(is, getImageType(imagePath), imgFile.getName(), Units.toEMU(100), Units.toEMU(100)); } } ``` 通过这些修改,可以确保: 1. 每个单元格内的图片按每行3排列 2. 图片间有适当间距 3. 布局稳定不会意外换行 4. 空图片情况有合理处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值