Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are my lines disappearing when I switch the deprecated drawLine() method for the version with moveTo / lineTo / stroke in Apache PDFBox 2.x?

Tags:

java

pdfbox

I am creating a table by this example: http://fahdshariff.blogspot.de/2010/10/creating-tables-with-pdfbox.html

Now I've switched from Apache PDFBox 1.8 to 2.0, so some methods now are deprecated, including the drawLine()-method.

The API changelog states that you have to use a combination of 3 other methods now to accomplish the task of drawing a line:

org.apache.pdfbox.pdmodel.PDPageContentStream.drawLine(float, float, float, float):
Use PDPageContentStream.moveTo(float, float) 
followed by PDPageContentStream.lineTo(float, float) 
followed by PDPageContentStream.stroke()

Therefore I've changed this line

final float tableWidth = page.findMediaBox().getWidth() - (2 * margin);

to this line:

final float tableWidth = page.getMediaBox().getWidth() - (2 * margin);

And changing these 2 lines

// draw the rows
contentStream.drawLine(margin, nexty, margin + tableWidth, nexty);
(...)
// draw the columns
contentStream.drawLine(nextx, y, nextx, y - tableHeight);

to this:

// draw the rows
contentStream.moveTo(margin, nexty);
contentStream.lineTo(margin, nexty);
contentStream.stroke();
(...)
// draw the columns
contentStream.moveTo(nextx, y - tableHeight);
contentStream.lineTo(nextx, y - tableHeight);
contentStream.stroke();

But if I do this, all the lines are gone and dont appear in the PDF:

emptyLines

Strangely, if I mix the deprecated drawLine()-method with the moveTo / lineTo / stroke-methods, I can get either the rows OR the columns:

// draw the rows
float nexty = y;
for (int i = 0; i <= rows; i++) {
    contentStream.drawLine(margin, nexty, margin + tableWidth, nexty);
    // contentStream.moveTo(margin, nexty);
    // contentStream.lineTo(margin, nexty);
    // contentStream.stroke();
    nexty -= rowHeight;
}

// draw the columns
float nextx = margin;
for (int i = 0; i <= cols; i++) {
    // contentStream.drawLine(nextx, y, nextx, y - tableHeight);
    contentStream.moveTo(nextx, y - tableHeight);
    contentStream.lineTo(nextx, y - tableHeight);
    contentStream.stroke();
    nextx += colWidth;
}

Has this result:

rowLines

Switching on the deprecated drawLine-method for the columns

// draw the rows
float nexty = y;
for (int i = 0; i <= rows; i++) {
    // contentStream.drawLine(margin, nexty, margin + tableWidth,
    // nexty);
    contentStream.moveTo(margin, nexty);
    contentStream.lineTo(margin, nexty);
    contentStream.stroke();
    nexty -= rowHeight;
}

// draw the columns
float nextx = margin;
for (int i = 0; i <= cols; i++) {
    contentStream.drawLine(nextx, y, nextx, y - tableHeight);
    // contentStream.moveTo(nextx, y - tableHeight);
    // contentStream.lineTo(nextx, y - tableHeight);
    // contentStream.stroke();
    nextx += colWidth;
}

has this result:

columnLines

So the maths behind this for drawin the lines seems to be okay. But somehow there is a side-effect I'm not understanding, so the lines disappear?

How can I switch the deprecated drawLine-method to a non-deprecated version?

The example-code is a MVCE, so if you want to test my problem, simply copy the example code from here into the editor of your choice: http://fahdshariff.blogspot.de/2010/10/creating-tables-with-pdfbox.html

like image 521
hamena314 Avatar asked Dec 18 '22 14:12

hamena314


1 Answers

contentStream.moveTo(margin, nexty);
contentStream.lineTo(margin, nexty);
contentStream.stroke();

Is a Point. It should be:

contentStream.moveTo(margin, nexty);
contentStream.lineTo(margin + tableWidth, nexty);
contentStream.stroke();

If you draw a vertical line, you have to respectively increment the y-coordinate:

contentStream.moveTo(nextx, y); 
contentStream.lineTo(nextx, y - tableHeight); 

I suggest you make a little helper method like this:

private void drawLine( PDPageContentStream content, float xstart, float ystart, float xend, float yend ){
    content.moveTo(xstart, ystart); // moves "pencil" to a position
    content.lineTo(xend, yend);     // creates an invisible line to another position
    content.stroke();               // makes the line visible
}
like image 82
Fildor Avatar answered Mar 01 '23 23:03

Fildor