JTable打印时无法占满整个页面宽度 两种打印模式均无效该如何解决
JTable打印无法占满页面宽度的解决方案
方案1:临时调整列宽适配页面(侵入性最低,优先推荐)
打印前先计算打印区域的可用宽度,按原有列宽比例重新分配所有列的宽度,打印完成后还原原有列宽配置即可。
// 1. 保存原始列配置 int columnCount = table.getColumnCount(); int[] originalWidths = new int[columnCount]; int[] originalMinWidths = new int[columnCount]; int[] originalMaxWidths = new int[columnCount]; for (int i = 0; i < columnCount; i++) { TableColumn col = table.getColumnModel().getColumn(i); originalWidths[i] = col.getWidth(); originalMinWidths[i] = col.getMinWidth(); originalMaxWidths[i] = col.getMaxWidth(); } // 2. 计算缩放比例 PrinterJob job = PrinterJob.getPrinterJob(); PageFormat pageFormat = job.defaultPage(); double printableWidth = pageFormat.getImageableWidth(); int totalOriginalWidth = 0; for (int w : originalWidths) totalOriginalWidth += w; double scale = printableWidth / totalOriginalWidth; // 3. 应用缩放后的列宽,临时放开宽限限制 for (int i = 0; i < columnCount; i++) { TableColumn col = table.getColumnModel().getColumn(i); col.setMinWidth(1); col.setMaxWidth(Integer.MAX_VALUE); col.setPreferredWidth((int) (originalWidths[i] * scale)); col.setWidth((int) (originalWidths[i] * scale)); } table.doLayout(); // 4. 执行打印 try { table.print(JTable.PrintMode.NORMAL, null, null, true, null, false); } catch (PrinterException e) { e.printStackTrace(); } // 5. 还原原始列配置 for (int i = 0; i < columnCount; i++) { TableColumn col = table.getColumnModel().getColumn(i); col.setMinWidth(originalMinWidths[i]); col.setMaxWidth(originalMaxWidths[i]); col.setPreferredWidth(originalWidths[i]); col.setWidth(originalWidths[i]); } table.doLayout();
方案2:自定义Printable实现强制控制绘制尺寸
如果默认打印逻辑存在无法绕过的限制,可以自己实现Printable接口,直接控制绘制时的缩放比例,强制占满页面宽度:
PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable((g, pf, pageIndex) -> { if (pageIndex > 0) return Printable.NO_SUCH_PAGE; Graphics2D g2d = (Graphics2D) g.create(); // 移动到可打印区域起点 g2d.translate(pf.getImageableX(), pf.getImageableY()); // 计算宽度缩放比例,高度等比缩放避免内容拉伸变形 double widthScale = pf.getImageableWidth() / table.getWidth(); g2d.scale(widthScale, widthScale); // 绘制表格 table.print(g2d); g2d.dispose(); return Printable.PAGE_EXISTS; }, job.defaultPage()); // 弹出打印对话框后执行打印 if (job.printDialog()) { try { job.print(); } catch (PrinterException e) { e.printStackTrace(); } }
常见失效场景排查
- 如果之前设置了
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF),打印前需要临时改为JTable.AUTO_RESIZE_ALL_COLUMNS,否则会导致PrintMode.FIT_WIDTH逻辑失效 - 如果JTable嵌套在JScrollPane中,打印前可以临时将table从父容器中移除,避免滚动视图的尺寸限制影响打印计算,打印完成后再恢复容器关系
内容的提问来源于stack exchange,提问作者Ahtap
相关产品推荐
相关产品推荐

