- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
之前我问过一个关于绘制自定义表格边框的问题:Draw custom borders for table spanning across more than one page in itext7
并且提供了一种绘制自定义边框的方法,但它不允许影响完整的行或列线(例如稍微倾斜),因为单元格边框是为每个单元格单独绘制的。
我想为表格边框添加一些随机性,如下面的屏幕截图所示:
这是我的代码,适用于适合单个页面的表格,但如果表格跨越多个页面,则代码不再起作用:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);
doc.add(new Paragraph("Table event"));
Table table = new Table(UnitValue.createPercentArray(3)).useAllAvailableWidth();
table.setNextRenderer(new DottedLineTableRenderer(table, new Table.RowRange(0, 0)));
String s ="";
for(int i=0;i<35;i++){
s+="\nTest";
}
table.addCell(new Cell().add(new Paragraph(s)).setBorder(Border.NO_BORDER));
table.addCell(new Cell().add(new Paragraph("A2")).setBorder(Border.NO_BORDER));
table.addCell(new Cell().add(new Paragraph("A3")).setBorder(Border.NO_BORDER));
doc.add(table);
doc.close();
private class DottedLineTableRenderer extends TableRenderer {
public DottedLineTableRenderer(Table modelElement, Table.RowRange rowRange) {
super(modelElement, rowRange);
}
@Override
public void drawChildren(DrawContext drawContext) {
super.drawChildren(drawContext);
PdfCanvas canvas = drawContext.getCanvas();
int maxLineTo = 5;
int minLineTo = 2;
int lineToHorizontalLine = (int)(Math.random() * maxLineTo) + minLineTo;
int maxSkewHor = 5;
int minSkewHor = 2;
int skewHorizontalLine = (int)(Math.random() * maxSkewHor) + minSkewHor;
int maxVerticalLine = 5;
int minVerticalLine = 2;
int lineToVerticalLine = (int)(Math.random() * maxVerticalLine) + minVerticalLine;
canvas.setLineWidth(2).setStrokeColor(new DeviceRgb(222, 27, 27));
// first horizontal line
CellRenderer[] cellRenderers = rows.get(0);
canvas.moveTo(cellRenderers[0].getOccupiedArea().getBBox().getLeft()-lineToHorizontalLine,
cellRenderers[0].getOccupiedArea().getBBox().getTop());
canvas.lineTo(cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getRight()+lineToHorizontalLine,
cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getTop());
for (int i = 0; i < rows.size(); i++) {
skewHorizontalLine = (int)(Math.random() * maxSkewHor) + minSkewHor;
lineToHorizontalLine = (int)(Math.random() * maxLineTo) + minLineTo;
cellRenderers = rows.get(i);
// horizontal lines
canvas.moveTo(cellRenderers[0].getOccupiedArea().getBBox().getX()-lineToHorizontalLine,
cellRenderers[0].getOccupiedArea().getBBox().getY()+skewHorizontalLine);
canvas.lineTo(cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getRight()+lineToHorizontalLine,
cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getBottom());
// first vertical line
Rectangle cellRect = cellRenderers[0].getOccupiedArea().getBBox();
canvas.moveTo(cellRect.getLeft(), cellRect.getBottom());
canvas.lineTo(cellRect.getLeft(), cellRect.getTop()+lineToVerticalLine );
// vertical lines
for (int j = 0; j < cellRenderers.length; j++) {
lineToVerticalLine = (int)(Math.random() * maxVerticalLine) + minVerticalLine;
cellRect = cellRenderers[j].getOccupiedArea().getBBox();
canvas.moveTo(cellRect.getRight(), cellRect.getBottom()-lineToVerticalLine);
canvas.lineTo(cellRect.getRight(), cellRect.getTop()+lineToVerticalLine); //ячейки
}
}
canvas.stroke();
}
}
我想自己绘制自定义边框:)
最佳答案
首先,我们需要正确重写渲染器,即重写getNextRenderer()
方法。目前,TableRenderer
的重写存在很大问题,因为 TableRenderer
的无参数构造函数不可访问,并且其他构造函数会执行一些更改状态的隐式工作。但我们仍然可以通过以下代码解决这个问题:
@Override
public IRenderer getNextRenderer() {
CustomTableRenderer nextTable = new CustomTableRenderer((Table) modelElement);
nextTable.rows.clear();
nextTable.rowRange = null;
return nextTable;
}
免责声明:由于答案使用了 TableRenderer
的私有(private)实现细节,因此将来可能无法工作。它适用于 7.1.6
,这是撰写本文时最新发布的版本。您应该为此目的创建一个自定义代码分支。 Pull requests也欢迎。
如果我们查看 TableRenderer
的实现,我们会发现该类包含 heights
( line in code ) 和 countedColumnWidth
( line in code ) )听起来很有趣的字段,但它们是私有(private)
。这意味着我们应该创建 iText 的自定义分支(源代码位于 https://github.com/itext/itext7 ),使这些字段 protected
并在我们的子类中使用它们。
您可以在代码中使用反射,风险自负,但不应该使用它,因为它可能不适用于您的 JVM(强烈建议不要更改可访问性修饰符)或者可能不适用于iText 的下一个版本,或者可能由于其他原因而无法工作。我不会在我的答案中添加反射代码以进一步阻止其使用。
我们需要做的就是重写drawBorders()
方法。下面的代码已经为线条添加了一些随机性。
private static class CustomTableRenderer extends TableRenderer {
public CustomTableRenderer(Table modelElement) {
super(modelElement);
}
@Override
public IRenderer getNextRenderer() {
CustomTableRenderer nextTable = new CustomTableRenderer((Table) modelElement);
nextTable.rows.clear();
nextTable.rowRange = null;
return nextTable;
}
@Override
protected void drawBorders(DrawContext drawContext) {
PdfCanvas canvas = drawContext.getCanvas();
canvas.saveState();
canvas.setStrokeColor(ColorConstants.RED);
Random r = new Random();
// Draw vertical lines
float curX = getOccupiedAreaBBox().getLeft();
for (int i = 0; i <= countedColumnWidth.length; i++) {
canvas.moveTo(curX, getOccupiedAreaBBox().getTop() + 3);
canvas.lineTo(curX + r.nextInt(4), getOccupiedAreaBBox().getBottom() - 3);
if (i < countedColumnWidth.length) {
float curWidth = countedColumnWidth[i];
curX += curWidth;
}
}
// Draw horizontal lines
float curY = getOccupiedAreaBBox().getBottom();
for (int i = 0; i <= heights.size(); i++) {
canvas.moveTo(getOccupiedAreaBBox().getLeft() - 3, curY);
canvas.lineTo(getOccupiedAreaBBox().getRight() + 3, curY + r.nextInt(4));
if (i < heights.size()) {
float curHeight = heights.get(i);
curY += curHeight;
}
}
canvas.stroke();
canvas.restoreState();
}
}
要激活自定义渲染器,请在添加到文档之前将其设置到表格:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Table table = new Table(UnitValue.createPercentArray(new float[]{30, 30}));
for (int i = 0; i < 40; i++) {
table.addCell(new Cell().add(new Paragraph("Hello")));
table.addCell(new Cell().add(new Paragraph("World")));
table.startNewRow();
}
table.setNextRenderer(new CustomTableRenderer(table));
doc.add(table);
结果表如下所示:
关于java - 在 itext7 中更灵活地绘制自定义表格边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56101827/
我有以下几行代码: using XXX.PAD.PaidServices; using YYY= XXX.PAD.PaidServices.Judet; //// uncomment below fo
我正在寻找一种方法,让 LAN 中的客户端无需任何配置即可找到我的服务器应用程序的所有实例。我不想自己破解某些东西,而是想使用现有的解决方案。就个人而言,我需要用 Python 完成它,但我很乐意听到
我的“问题”或“挑战”有很多问题。但它们都不符合我的需求。好的,我开始了: 我想要一个保存可变属性的数据库。现在我将它们作为列名“硬编码”到数据库中(参见图片)。请参阅“颜色”和“尺寸”。但是如果我想
我正在为我的一个 friend 创建一个网站。我们得到了这些布局,我已经放了一个灵活的背景,可以缩放到当前的浏览器大小。但是放置在背景上的图标需要在缩放窗口时保持相对位置。意味着如果我调整窗口大小,让
案例 通常,您会使用 cellForRowAtIndexPath 委托(delegate)方法来设置单元格。单元格的信息集对于单元格的绘制方式和大小非常重要。 不幸的是,heightForRowAtI
我试图让下面的 div 变得灵活 div { min-width: 500px; max-width: 1000px; width:100%; height: 400px; margin-left:1
我在单元测试方面遇到问题。当我运行测试时,它以 "No tests found" 结束。我正在使用 AppCode 和 Quick/Nimble 框架进行单元测试,但它在 XCode 中也不起作用。
问之前,请理解我的英语不好。 我在 servlet 编程中使用 Class.forName(...) 类。当我访问 servlet 时,我从数据库中获得一行详细的 Controller 信息,指示要使
我创建了一个cron job在 GAE 灵活环境中,每 15 分钟自动运行一次。 但是在创建每个实例时,是否会为每个实例复制相同的 cron 作业?我对此不太确定。 最佳答案 不,不会为每个实例复制
div A 灵活且固定(位于窗口顶部),具有高 z-index,因此下方的元素可以在滚动时从下方通过。 div B 位于 div A 下方,我希望它“粘”在 div A 的底部,因为在调整窗口大小时高
我是 Quick/Nimble 的新手,所以我尝试了一个简单的单元测试: import Quick import Nimble class DarkSkyTests: QuickSpec {
我创建了一个演示。关于表格单元格的灵 active ,我需要一些帮助。 我有一些表格单元格,它们的宽度应该是固定的。 但单元格由标签组成,标签可以是长文本,也可以是短文本。 基于此标签,表格单元格应该
我非常熟悉在代码中需要“水平带”的网站 - 即使他们的内容固定在 960 像素以内,他们的背景也会向左和向右“延伸”。 我知道如何做这些,如果它们只有一种颜色,或者我可以用作背景的一张图片。 最近一位
我在自己编写的网站(无框架或 CMS)上使用 Cloudflare Flexible SSL。一切正常,现在我想在整个网站上使用 HTTPS。我在 Apache Web 服务器上使用 PHP。 我想知
我有这个 Java 接口(interface): public interface Box { public void open(); public void close(); } 这个接
所以我有一个“主要”功能系统,现在可以作为 CMS 使用:用户进入编辑器并从四个模板中选择一个。在模板中,他们单击可以添加图像、文本或两者的部分。 我有一个预览屏幕,可以向他们展示他们正在制作的东西,
下面的 HTML/CSS/Javascript (jQuery) 代码显示了 #makes 选择框。选择一个选项会显示带有相关选项的 #models 选择框。 #makes 选择框偏离中心,#mode
我正在使用固定高度的图像来填充具有渐变颜色的 div,方法如下:背景:透明 url(green_bg.gif) repeat-x scroll 0 0; 但是它只填充一个等于图像高度的高度。根据其中的
我的系统的 GUI 在 1366 X 768 分辨率下运行良好。当它以不同的分辨率显示时,我需要并排滚动,而它不应该这样。此外,当我尝试在 chrome 中按 ctr+- 时,div 和部分变得困惑。
我正在尝试在 google app engine 灵活环境中使用 python 编写日志。 我想使用默认的 python 日志记录库并使用处理程序进行日志记录。这是我的代码: import loggi
我是一名优秀的程序员,十分优秀!