Problem with loop over new page
See original GitHub issueBug Report
When adding text in a loop which is creating an overflow (new page) the text is not placed correctly on the new pages and will create an new page for every doc.text()
function
Description of the problem
I add some details on a page using an async loop. Every iteration use the same doc.y height. At the end of the iteration I will move down and use the new y position. That’s works correctly until the end the page. Pdfkit is automatically creating a new page which is great, but is repeating that for every single time that doc.text()
is called for a few times. Then, the rest of the text is printed correctly at the last page. You can see it on the attached PDF file with dummy data,
Code sample
var pdf = new PDFDocument({
size: doc.size,
layout: 'landscape',
margins: {
top: 50,
bottom: 50,
left: 50,
right: 50
}
})
pdf.info['Author'] = 'Author';
pdf.info['Title'] = 'Purchase Order';
pdf.lineWidth(0.5);
pdf.fontSize(20);
pdf.font('Helvetica-Bold');
pdf.text('Purchase Order', doc.margins.left, doc.margins.top);
pdf.font('Helvetica');
pdf.moveDown(1);
pdf.fontSize(10);
pdf.text('Supplier: ' + purchaseOrder.company.name);
pdf.moveUp(1);
pdf.text('Status: ' + purchaseOrder.status[purchaseOrder.status.length - 1].status, doc.margins.right, pdf.y, { align: 'right' });
pdf.moveDown(2);
pdf.text('Delivery Address:');
pdf.text('Foo Lane 23');
pdf.text('1234AB Foo city');
pdf.text('Netherlands');
pdf.moveDown(2);
var pageWidth = pdf.page.width - doc.margins.right - doc.margins.left;
var numberWidth = Math.round(((12 / 100) * pageWidth) * 100 / 100);
var nameWidth = Math.round(((40 / 100) * pageWidth) * 100 / 100);
var amountWidth = Math.round(((12 / 100) * pageWidth) * 100 / 100);
var receivedWidth = Math.round(((12 / 100) * pageWidth) * 100 / 100);
var priceWidth = Math.round(((12 / 100) * pageWidth) * 100 / 100);
var stockWidth = Math.round(((12 / 100) * pageWidth) * 100 / 100);
pdf.font('Helvetica-Bold');
pdf.text('Products');
pdf.font('Helvetica');
var y = pdf.y;
pdf.text('Number', doc.margins.left, y, { width: numberWidth, height: 60 })
pdf.text('Article name', doc.margins.left + numberWidth, y, { width: nameWidth, height: 60 })
pdf.text('Amount', doc.margins.left + numberWidth + nameWidth, y, { width: amountWidth, height: 60 })
pdf.text('Received', doc.margins.left + numberWidth + nameWidth + amountWidth, y, { width: receivedWidth, height: 60 });
pdf.text('Retail price', doc.margins.left + numberWidth + nameWidth + amountWidth + receivedWidth, y, { width: priceWidth, height: 60 })
pdf.text('In stock', doc.margins.left + numberWidth + nameWidth + amountWidth + receivedWidth + priceWidth, y, { width: stockWidth, height: 60 });
pdf.moveDown(0.8)
pdf.lineCap("butt").moveTo(doc.margins.left, pdf.y).lineTo(pdf.page.width - doc.margins.right, pdf.y).stroke();
pdf.moveDown(0.5)
var y = pdf.y;
var totalAmount = 0, totalReceived = 0, totalPrice = 0, totalStock = 0;
async.forEachOf(purchaseOrder.items, function (item, key, itemsDone) {
var text = item.product_id ? item.product_id.variants[0].productNumber : item.number ? item.number : '';
pdf.text(text, doc.margins.left, y, { width: numberWidth});
pdf.text(item.name, doc.margins.left + numberWidth, y, { width: nameWidth});
pdf.text(item.price, doc.margins.left + numberWidth + nameWidth, y, { width: amountWidth,});
pdf.text(item.receivedQuantity, doc.margins.left + numberWidth + nameWidth + amountWidth, y, { width: receivedWidth});
pdf.text(item.price, doc.margins.left + numberWidth + nameWidth + amountWidth + receivedWidth, y, { width: priceWidth});
pdf.text(item.stock, doc.margins.left + numberWidth + nameWidth + amountWidth + receivedWidth + priceWidth, y, { width: stockWidth});
totalAmount += parseFloat(item.price);
totalReceived += parseInt(item.receivedQuantity);
totalPrice += parseFloat(item.price);
totalStock += parseInt(item.stock);
pdf.moveDown();
y = pdf.y;
itemsDone();
}, function () {
pdf.moveUp(0.5);
pdf.lineCap("butt").moveTo(doc.margins.left, pdf.y).lineTo(pdf.page.width - doc.margins.right, pdf.y).stroke();
pdf.moveDown(0.5);
var y = pdf.y;
pdf.text("Total", doc.margins.left + numberWidth, y, { width: nameWidth});
pdf.text(totalAmount, doc.margins.left + numberWidth + nameWidth, y, { width: amountWidth});
pdf.text(totalReceived, doc.margins.left + numberWidth + nameWidth + amountWidth, y, { width: receivedWidth });
pdf.text(totalPrice, doc.margins.left + numberWidth + nameWidth + amountWidth + receivedWidth, y, { width: priceWidth});
pdf.text(totalStock, doc.margins.left + numberWidth + nameWidth + amountWidth + receivedWidth + priceWidth, y, { width: stockWidth});
pdf.end();
pdf.pipe(res);
})
Your environment
- pdfkit version: 0.9.0
- Node version: 8.11.3
- Operating System: Windows 10
Issue Analytics
- State:
- Created 5 years ago
- Comments:10 (2 by maintainers)
Top Results From Across the Web
Opening the page fails in for loop when called more than 1 time
page.open() is an asynchronous function. If you call it in a loop, then it the loop will be fully executed before even the...
Read more >Problem: Loop for each Tab in Web page does not Sa...
I start a new flow → launched new iteration of chrome browser with web page → extracted data from web page as the...
Read more >Smartform - Loop and newpage issue - SAP Community
Passing my inertnal table to smartfom, inside smart form I am looping on this internal table. But the form is only showing one...
Read more >JavaScript For Loop Click Event ← Issues & Solutions Explained
When you attach multiple click events inside a for loop in JavaScript, It always gives the last index regardless of what button is...
Read more >Looping code - Learn web development | MDN
Here we'll look at the loop structures available in JavaScript that ... each one of which draws a circle in a random position...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hey I just found something which work for me:
You need to keep the track of you current Y position In my case, if more than 680, I create a new page and reset the Y position to 50.
Hi all, the problem is the async foreach. The moveDown is not syncing the doc.y every call. My way is make the “complete” PDF generation procedure in a async void/Promise.