dhorions / boxable

Boxable is a library that can be used to easily create tables in pdf documents.
http://dhorions.github.io/boxable/
Apache License 2.0
334 stars 154 forks source link

A lot of warning message when draw a table #55

Closed jsyzthz closed 8 years ago

jsyzthz commented 8 years ago

Hi this is a great tools to generate a table using pdfbox. but i found a lot of message on the background log. such as:

Apr 29, 2016 1:54:45 PM org.apache.pdfbox.contentstream.operator.graphics.ClosePath process
WARNING: ClosePath without initial MoveTo

my configuration incorrect? how to remove ? thanks!

dobluth commented 8 years ago

Hi!

Could you provide a minimal code example? Which version of Boxable are you using?

jsyzthz commented 8 years ago

sorry,

PDPage page = createBlankPage();//TODO
PDRectangle boundingBox = page.getBBox();
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
    renderHeader(page, contentStream);
    float y = boundingBox.getHeight() - HEADER_LINE_OFFSET - BODY_MARGIN_TOP;
    // draw header
    contentStream.beginText();
    contentStream.setFont(getBodyFont(), FONT_SIZE_H1);
    y -= FONT_SIZE_H1;
    contentStream.newLineAtOffset(MARGIN_LEFT, y);
    contentStream.showText("Test");
    contentStream.endText();

    BaseTable table = new BaseTable(y - 24, y, 24, 10, boundingBox.getWidth() - MARGIN_RIGHT - MARGIN_LEFT,
            MARGIN_LEFT, document, page, true, true, new TestPageProvider(document, boundingBox));

    generateResultTableHeader(table);
    for (int i = 0; i < 19; i++) {
        Test t = TestData.get(i);
        generateResultTableData(table, t);
    }
    table.draw();
}

private Row<PDPage> generateResultTableHeader(BaseTable table) throws IOException {
    Row<PDPage> headerRow = table.createRow(15F);
    createCell(headerRow,"C1", 5F, Color.LIGHT_GRAY);
    ...//A lot of column
}

private Row<PDPage> generateResultTableData(BaseTable table, Test test) throws IOException {
    Row<PDPage> row = table.createRow(10F);
    createCell(row, test.getT1(), null, null);
    ...
}

private Cell<PDPage> createCell(Row<PDPage> row, String value, Float width, Color fillColor) throws IOException {
    Cell<PDPage> cell = null;
    if (width != null) {
        cell = row.createCell(width.floatValue(), value);
    } else {
        cell = row.createCell(value);
    }
    cell.setFont(getBodyFont());
    cell.setAlign(HorizontalAlignment.CENTER);
    cell.setValign(VerticalAlignment.MIDDLE);
    if (fillColor != null) {
        cell.setFillColor(fillColor);
    }
    return cell;
}

private class TestPageProvider extends DefaultPageProvider {

    public TestPageProvider(PDDocument document, PDRectangle size) {
        super(document, size);
    }

    @Override
    public PDPage nextPage() {
        PDPage pdPage = super.createPage();
        PDRectangle boundingBox = pdPage.getBBox();
        try (PDPageContentStream contentStream = new PDPageContentStream(document, pdPage)) {
            renderHeader(pdPage, contentStream);
            float y = boundingBox.getHeight() - HEADER_LINE_OFFSET - BODY_MARGIN_TOP;
            // draw header
            contentStream.beginText();
            contentStream.setFont(getBodyFont(), FONT_SIZE_H1);
            y -= FONT_SIZE_H1;
            contentStream.newLineAtOffset(MARGIN_LEFT, y);
            contentStream.showText(resources.getString("title.resultTable"));
            contentStream.endText();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return pdPage;
    }
}
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.1</version>
</dependency>

<dependency>
    <groupId>com.github.dhorions</groupId>
    <artifactId>boxable</artifactId>
    <version>1.4</version>
</dependency>
jsyzthz commented 8 years ago

pdfbox 2.0.0 also can see this warning message. BTW, i want to draw a table in a new page ,and each page has same header and footer, so i create a TestPageProvider. but my first line code also has method(createBlankPage) to create a new blank page. how to keep one place to create a new page? Thanks.

dobluth commented 8 years ago

Hi,

I am sorry, I cannot reproduce this issue. I cannot use your code example, because too much is missing (the Test class, several method calls and constants, ....). Please stick to a minimal example which is producing the undesired log messages. Could you please provide such an example?

In the test case included in Boxable (TableTest.Sample1) I cannot see any of those log messages.

As for the method createBlankPage: we are aware of this problem and are currently discussing API changes for the new release (started in #20 and continued on gitter, feel free to join ;)). For the moment you can at least avoid the code duplication by using the already present method in your own PageProvider, so instead of

PDPage firstPage = createBlankPage();

use

PageProvider pageProvider = new TestPageProvider();
PDPage firstPage = pageProvider.nextPage();

assuming you also want to render the header on the first page.

Another hint: Boxable offers the method PDStreamUtils.write() to write text to the page, maybe you want to use it.

jsyzthz commented 8 years ago

Hi i create a sample with a little code, but i cannot reproduce this issue. i think close it first. Thanks a lot!

Krkrkrtek commented 8 years ago

Hi, I run to same problem as jsyzthz. Except I try to create simplest program to demonstrate it and with success. In simple way, I'm creating program to create PDF files with PDFBox and with your awesome library I can add tables with minimal effort. Today I tryed to make preview before i save PDF and i found an easy way to do it with swing components and BufferedImage. Though it looks exactly how i want, it starts to fill console with a lot of warnings like this:

IX 15, 2016 1:21:52 ODP. org.apache.pdfbox.contentstream.operator.graphics.ClosePath process
WARNING: ClosePath without initial MoveTo

So I was looking for solution and found this topic. From my testing it looks like problem with renderer. Here is my simplest code to demonstrate it: (I just create one big cell on a page)

import be.quodlibet.boxable.BaseTable;
import be.quodlibet.boxable.Cell;
import be.quodlibet.boxable.Row;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.rendering.PDFRenderer;

public class Test {

    public static void main(String[] args) throws IOException {
        PDRectangle pageSize = PDRectangle.A4;
        PDPage page = new PDPage(pageSize);
        PDDocument doc = new PDDocument();
        doc.addPage(page);

        BaseTable table = new BaseTable(pageSize.getHeight(), pageSize.getHeight(),
            0, pageSize.getWidth(), 0, doc, page, false, true);

        Row<PDPage> row = table.createRow(100.0f);
        Cell<PDPage> cell = row.createCell(100.0f, "Simplest test i can create ;)");

        try {
            table.draw();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        PDFRenderer renderer = new PDFRenderer(doc);
        BufferedImage imPage = renderer.renderImage(0); //this is throwing warnings

        try {
            doc.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

I'm using PDFBox 2.0.2 and boxable 1.4 Am I doing something wrong? Thanks for reply ;)

Frulenzo commented 8 years ago

yeah, it seems the problem is in the pdfbox rendering, particulary in drawPage() method in PageDrawer class. I tried to make BufferedImage in our other test cases and I also get something just like you:

WARNUNG: ClosePath without initial MoveTo
Sep 16, 2016 3:43:51 PM org.apache.pdfbox.contentstream.operator.graphics.ClosePath process

Sorry that I can't help you more with this.