【问题标题】:On creating a table having rounded corner with itext, the size of PDF is increasing unexpectedly在使用 itext 创建具有圆角的表格时,PDF 的大小意外增加
【发布时间】:2022-01-03 06:58:44
【问题描述】:

我正在同一个 PDF 上创建多个表格。我需要表格的圆角,单元格的边框颜色和表格的边框颜色应该不同。我已经创建了相同的表格渲染器,在使用渲染器创建表格时,PDF 大小随机增加。如果我们不使用圆角,则 PDF 大小为“61KB”,如果我使用渲染器制作圆角,则 PDF 大小为“500KB”。请建议如何解决

import java.io.FileNotFoundException;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.TableRenderer;

public class testDate {

public static void main(String[] args) throws FileNotFoundException {
    String dest = "D://PDF_SIZE.pdf";
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    pdf.addNewPage();
    Document doc = new Document(pdf);
    for (int i =0 ; i< 1130 ; i++){
        Table table = new Table(new float[]{100f,100f});
        table.setWidth(506.25f);
        table.setProperty(com.itextpdf.layout.property.Property.TABLE_LAYOUT, "fixed");

        com.itextpdf.layout.element.Cell cell = new com.itextpdf.layout.element.Cell(1,1);
        cell.setWidth(15.165f);
        Text t =new Text("A").setFontSize(11f);
        Paragraph p = new Paragraph();
        p.setFixedLeading(0.0f).setMultipliedLeading(0.86f);
        cell.add(p.add(t));
        cell.setPadding(3f);
        cell.setMinHeight(10f);
        cell.setVerticalAlignment(VerticalAlignment.TOP);
        cell.setTextAlignment(TextAlignment.LEFT);
        cell.setKeepTogether(true);
        cell.setBorder(new SolidBorder(new DeviceRgb(255,0,0),0.5f));
        cell.setBackgroundColor(new DeviceRgb(255,255,255));
        table.addCell(cell);

        com.itextpdf.layout.element.Cell cell2 = new com.itextpdf.layout.element.Cell(1,1);
        cell2.setWidth(490.33502f);
        Text t2 =new Text("Row Number - " + i).setFontSize(11f);
        Paragraph p2 = new Paragraph();
        p2.setFixedLeading(0.0f).setMultipliedLeading(0.86f);
        cell2.add(p2.add(t2));
        cell2.setPadding(3f);
        cell2.setMinHeight(10f);
        cell2.setVerticalAlignment(VerticalAlignment.TOP);
        cell2.setTextAlignment(TextAlignment.LEFT);
        cell.setKeepTogether(true);
        cell2.setBorder(new SolidBorder(new DeviceRgb(255,0,0),0.5f));
        cell2.setBackgroundColor(new DeviceRgb(255,255,255));
        table.addCell(cell2);
        table.setNextRenderer(new TableBorderRenderer (table));
        doc.add(table);

    }
    doc.close();
    System.out.println("table Added.");
}


public static  class TableBorderRenderer extends TableRenderer {


    public TableBorderRenderer(Table modelElement) {
        super(modelElement);

    }

    @Override
    public IRenderer getNextRenderer() {
        return new TableBorderRenderer((Table) modelElement);
    }


    @Override
    protected void drawBorders(DrawContext drawContext) {
        Rectangle rect = getOccupiedAreaBBox();
        PdfPage currentPage = drawContext.getDocument().getPage(getOccupiedArea().getPageNumber());

        PdfCanvas aboveCanvas = new PdfCanvas(currentPage.newContentStreamAfter(), currentPage.getResources(), drawContext.getDocument());
        float lineWidth = 0.5f;
        rect.applyMargins(lineWidth / 2, lineWidth / 2, lineWidth / 2, lineWidth / 2, false);
        Color strokeColor;
        strokeColor = new DeviceRgb(255,255,0);
        aboveCanvas.saveState().setLineWidth(0.5f).setStrokeColor(new DeviceRgb(255,255,255)).rectangle(rect).stroke().restoreState();
        aboveCanvas.saveState().setLineWidth(0.5f).setStrokeColor(strokeColor).roundRectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight(), 5).stroke().restoreState();
        super.drawBorders(drawContext);
    }

    @Override
    public void drawChildren(DrawContext drawContext) {
        Rectangle rect = getOccupiedAreaBBox();
        float lineWidth = 0.5f;
        rect.applyMargins(lineWidth, lineWidth, lineWidth, lineWidth, false);
        PdfCanvas canvas = drawContext.getCanvas();
        canvas.saveState();
        canvas.roundRectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight(), 4.5f);
        canvas.clip().endPath();
        super.drawChildren(drawContext);
        canvas.restoreState();
    }
    }
}

【问题讨论】:

  • @Alexey Subach 因为此代码的灵感来自您在https://stackoverflow.com/questions/62788267/how-to-apply-background-color-to-table-cell-with-round-corners-in-itext7 中建议的代码。如果您能就这个问题提供您的建议,这将是很大的帮助。谢谢

标签: java itext itext7


【解决方案1】:

由于您在循环内部而不是在循环外部创建了一个表,因此您创建了 1130 个表而不是 1 个。这是最大的问题,它阻止您利用您在 cmets 中提到的 SO 答案的想法。

如果您像我在下面的 sn-p 中所做的那样将表创建放在循环之外,那么生成的 PDF 的大小将从 521 Kb 减少到 51 Kb。如果您禁用为此类代码设置自定义表格渲染器,则生成的 PDF 将为 45 Kb 大小。

    Table table = new Table(new float[] {100f, 100f});
    table.setWidth(506.25f);
    table.setFixedLayout();

    for (int i =0 ; i < 1130 ; i++) {
        // each iteration of this loop represents adding of a single row
        // some code
    }

    doc.add(table);

这是生成的 PDF 现在的样子:

正如您在问题中所问的,它具有黄色圆形表格边框、单元格背景(您在代码中设置为白色)和红色单元格边框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2018-04-08
    • 2014-04-03
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多