- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
有人知道 Java 的(最好是开源的)PDF 布局引擎,能够呈现带有水平分页符的表格吗? “水平分页”至少是该功能在 BIRT 中的命名方式,但要澄清一下:如果表格有太多列无法适应可用的页面宽度,我希望表格在多个页面中水平拆分,例如对于 10 列的表,第一页输出第 1-4 列,第二页输出第 5-10 列。当然,如果表格的行太多而无法垂直放置在一页上,这当然也应该在后面的页面上重复。
到目前为止,搜索产品非常困难。我认为这样的功能在其他产品中可能会有不同的命名,因此很难使用阿姨谷歌找到合适的解决方案。
到目前为止,我已经尝试过:
BIRT 声称支持这一点,但实际的实现是如此的错误,以至于无法使用。我认为这样的功能是不言而喻的,行高在所有页面上保持一致,从而可以在将页面彼此相邻放置时对齐行。然而,BIRT 会为每个页面单独计算所需的行高。
Jasper 不支持。
我也考虑过 Apache FOP,但我在 XSL-FO 规范中找不到任何合适的语法。
不管怎样,iText 对于这个任务来说通常有点太“低级”了(使得对预期 PDF 文档的其他部分进行布局变得困难),但似乎不提供支持。
由于似乎有几十个其他报告或布局引擎,它们可能适合也可能不适合,而且我发现要准确猜测要查找的内容有点困难,我希望有人可能已经有类似的要求并且可以至少提供一个正确方向的建议。产品可以很容易地集成到 Java 服务器应用程序中是相对重要的,本地 Java 库将是理想的。
现在,要保持所有页面的行对齐,必须按如下方式计算行高:
Row1.height = max(A1.height, B1.height, C1.height, D1.height)
Row2.height = max(A2.height, B2.height, C2.height, D2.height)
虽然 BIRT 目前似乎在做类似的事情:
Page1.Row1.height = max(A1.height, B1.height)
Page2.Row1.height = max(C1.height, D1.height)
Page1.Row2.height = max(A2.height, B2.height)
Page2.Row2.height = max(C2.height, D2.height)
最佳答案
可以使用 iText
以您想要的方式显示表格。您需要使用自定义表格定位和自定义行列写入。
我能够适应 this iText example在多个页面上水平和垂直书写。这个想法是记住在页面上垂直进入的开始行和结束行。我已经把整个代码都放好了,这样你就可以轻松运行它了。
public class Main {
public static final String RESULT = "results/part1/chapter04/zhang.pdf";
public static final float PAGE_HEIGHT = PageSize.A4.getHeight() - 100f;
public void createPdf(String filename)
throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(filename));
// step 3
document.open();
//setup of the table: first row is a really tall one
PdfPTable table = new PdfPTable(new float[] {1, 5, 5, 1});
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 50; i++) {
sb.append("tall text").append(i + 1).append("\n");
}
for(int i = 0; i < 4; i++) {
table.addCell(sb.toString());
}
for (int i = 0; i < 50; i++) {
sb = new StringBuilder("some text");
table.addCell(sb.append(i + 1).append(" col1").toString());
sb = new StringBuilder("some text");
table.addCell(sb.append(i + 1).append(" col2").toString());
sb = new StringBuilder("some text");
table.addCell(sb.append(i + 1).append(" col3").toString());
sb = new StringBuilder("some text");
table.addCell(sb.append(i + 1).append(" col4").toString());
}
// set the total width of the table
table.setTotalWidth(600);
PdfContentByte canvas = writer.getDirectContent();
ArrayList<PdfPRow> rows = table.getRows();
//check every row height and split it if is taller than the page height
//can be enhanced to split if the row is 2,3, ... n times higher than the page
for (int i = 0; i < rows.size(); i++) {
PdfPRow currentRow = rows.get(i);
float rowHeight = currentRow.getMaxHeights();
if(rowHeight > PAGE_HEIGHT) {
PdfPRow newRow = currentRow.splitRow(table,i, PAGE_HEIGHT);
if(newRow != null) {
rows.add(++i, newRow);
}
}
}
List<Integer[]> chunks = new ArrayList<Integer[]>();
int startRow = 0;
int endRow = 0;
float chunkHeight = 0;
//determine how many rows gets in one page vertically
//and remember the first and last row that gets in one page
for (int i = 0; i < rows.size(); i++) {
PdfPRow currentRow = rows.get(i);
chunkHeight += currentRow.getMaxHeights();
endRow = i;
//verify against some desired height
if (chunkHeight > PAGE_HEIGHT) {
//remember start and end row
chunks.add(new Integer[]{startRow, endRow});
startRow = endRow;
chunkHeight = 0;
i--;
}
}
//last pair
chunks.add(new Integer[]{startRow, endRow + 1});
//render each pair of startRow - endRow on 2 pages horizontally, get to the next page for the next pair
for(Integer[] chunk : chunks) {
table.writeSelectedRows(0, 2, chunk[0], chunk[1], 236, 806, canvas);
document.newPage();
table.writeSelectedRows(2, -1, chunk[0], chunk[1], 36, 806, canvas);
document.newPage();
}
document.close();
}
public static void main(String[] args) throws IOException, DocumentException {
new Main().createPdf(RESULT);
}
}
我了解可能 iText
仅用于报告的级别太低,但它可以与标准报告工具一起使用,以满足此类特殊需求。
更新:现在首先拆分高于页面高度的行。如果行高 2、3、...、n 倍,则代码不会进行拆分,但也可以对此进行调整。
关于java - PDF 中带有水平分页符的表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15361120/
我是一名优秀的程序员,十分优秀!