- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 iText7 测试一些东西,我有一个场景,我需要在顶部有 DocumentRenderer 段落,然后在同一页面上在其正下方启动 ColumnDocumentRender 2 列。我遇到的问题是,当我更改同一页面上的内容时,它会将 DocumentRenderer 中的内容与 ColumnDocumentRenderer 中的内容重叠。我相信这是因为一个渲染不知道另一个渲染,并且内容从页面顶部开始。我关注了this tutorial但它只显示如何将内容添加到下一页。它确实说
we'll have to instruct iText not to flush the content to the OutputStream
但是谁能告诉我具体如何实现这一目标?
public void createPdf(String dest) throws IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
Paragraph p = new Paragraph()
.add("Be prepared to read a story about a London lawyer "
+ "named Gabriel John Utterson who investigates strange "
+ "occurrences between his old friend, Dr. Henry Jekyll, "
+ "and the evil Edward Hyde.");
document.add(p);
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
... // Define column areas
document.setRenderer(new ColumnDocumentRenderer(document, columns));
document.add(new AreaBreak(AreaBreakType.LAST_PAGE));
... // Add novel in two columns
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
document.setRenderer(new DocumentRenderer(document));
document.add(new AreaBreak(AreaBreakType.LAST_PAGE));
p = new Paragraph()
.add("This was the story about the London lawyer "
+ "named Gabriel John Utterson who investigates strange "
+ "occurrences between his old friend, Dr. Henry Jekyll, "
+ "and the evil Edward Hyde. THE END!");
document.add(p);
document.close();
}
我需要这样的东西:
Whenever you create a new DocumentRenderer, iText starts returns to the top of the document –that is: from the first page. This allows you to use different renderers on the same document next to each other on the same page. If that is needed, we'll have to instruct iText not to flush the content to the OutputStream; otherwise we won't have access to previous pages. In this case, we don't need to change anything on previous pages. We just want to switch to another renderer on the next page. Introducing a page break that goes to the last page will avoid that new content overwrites old content.
最佳答案
我已获取此代码:C02E08_JekyllHydeV4
我根据您的问题更新了它:
//Initialize PDF document
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
// Initialize document
Document document = new Document(pdf);
Paragraph p = new Paragraph()
.add("Be prepared to read a story about a London lawyer "
+ "named Gabriel John Utterson who investigates strange "
+ "occurrences between his old friend, Dr. Henry Jekyll, "
+ "and the evil Edward Hyde.");
document.add(p);
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
//Set column parameters
...
//Define column areas
...
document.setRenderer(new ColumnDocumentRenderer(document, columns));
document.add(new AreaBreak(AreaBreakType.LAST_PAGE));
// Add the full Jekyl and Hyde text
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
document.setRenderer(new DocumentRenderer(document));
document.add(new AreaBreak(AreaBreakType.LAST_PAGE));
p = new Paragraph()
.add("This was the story about the London lawyer "
+ "named Gabriel John Utterson who investigates strange "
+ "occurrences between his old friend, Dr. Henry Jekyll, "
+ "and the evil Edward Hyde. THE END!");
document.add(p);
//Close document
document.close();
结果如下所示:
我认为这就是您正在寻找的行为。如果不是,请解释哪里出了问题。
更新:
明确问题后,显然上述答案并不能解决问题。这是实际问题的解决方案:
我们需要创建一个自定义的 ParagraphRenderer
来确定 Y 位置: MyParagraphRenderer 类扩展了 ParagraphRenderer {
float y;
public MyParagraphRenderer(Paragraph modelElement) {
super(modelElement);
}
@Override
public void drawBorder(DrawContext drawContext) {
super.drawBorder(drawContext);
y = getOccupiedAreaBBox().getBottom();
}
public float getY() {
return y;
}
}
当我们添加第一段时,我们需要使用这个自定义的ParagraphRenderer
:
Paragraph p = new Paragraph()
.add("Be prepared to read a story about a London lawyer "
+ "named Gabriel John Utterson who investigates strange "
+ "occurrences between his old friend, Dr. Henry Jekyll, "
+ "and the evil Edward Hyde.");
MyParagraphRenderer renderer = new MyParagraphRenderer(p);
p.setNextRenderer(renderer);
document.add(p);
我们现在可以像这样获取我们需要的 Y 位置:renderer.getY()
;我们使用这个 Y 位置来定义第一组列:
float offSet = 36;
float gutter = 23;
float columnWidth = (PageSize.A4.getWidth() - offSet * 2) / 2 - gutter;
float columnHeight1 = renderer.getY() - offSet * 2;
Rectangle[] columns1 = {
new Rectangle(offSet, offSet, columnWidth, columnHeight1),
new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight1)};
我们可以使用这组列来创建一个ColumnDocumentRenderer
,但是如果需要多个页面来渲染所有内容,那么第二页上的列的偏移量将会是错误的,因此我们还创建了一个自定义的 ColumnDocumentRenderer:
class MyColumnDocumentRenderer extends ColumnDocumentRenderer {
Rectangle[] columns2;
public MyColumnDocumentRenderer(Document document, Rectangle[] columns1, Rectangle[] columns2) {
super(document, columns1);
this.columns2 = columns2;
}
@Override
protected PageSize addNewPage(PageSize customPageSize) {
PageSize size = super.addNewPage(customPageSize);
columns = columns2;
return size;
}
}
此ColumnDocumentRenderer
接受两组列,一组将在第一页上使用,第二组将在所有后续页面上使用。这就是我们定义和应用自定义ColumnDocumentRenderer
的方式:
float columnHeight2 = PageSize.A4.getHeight() - offSet * 2;
Rectangle[] columns2 = {
new Rectangle(offSet, offSet, columnWidth, columnHeight2),
new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight2)};
document.setRenderer(new MyColumnDocumentRenderer(document, columns1, columns2));
现在结果如下所示:
根据您想要的第一个全页段落与列中后续内容之间的距离,您可以调整 renderer.getY() - offSet * 2
的值。
关于java - 在同一页面中在 ColumnDocumentRenderer 和 DocumentRenderer 之间切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51084709/
我正在使用 iText7 测试一些东西,我有一个场景,我需要在顶部有 DocumentRenderer 段落,然后在同一页面上在其正下方启动 ColumnDocumentRender 2 列。我遇到的
我正在尝试在我的 PDF 生成器中使用 Unicode 字符。我首先使用 PDFsharp 为页面创建主要布局(例如每个页面上的水印和形状),然后尝试使用 MigraDoc 添加文本。虽然在 PDFs
我是一名优秀的程序员,十分优秀!