49
votes

what I'm doing is using jsPDF to create a PDF of the graph I generated. However, I am not sure how to wrap the title (added by using the text() function). The length of the title will vary from graph to graph. Currently, my titles are running off the page. Any help would be appreciated!

This is the code i have so far:

var doc = new jsPDF();
doc.setFontSize(18);
doc.text(15, 15, reportTitle);
doc.addImage(outputURL, 'JPEG', 15, 40, 180, 100);
doc.save(reportTitle);

Nothing to keep the reportTitle from running off the page

7
Welcome to SO! You should expand your question a bit - show us what you've tried, what your expected result is, and what you're actually getting. - Kryten
I've added the bit of code I'm using to create the document. And as I've stated, sometimes the reportTitle is too long and runs off the right side of the PDF. Instead, I want to make it wrap somehow. - user3749946

7 Answers

112
votes

Okay I've solved this. I used the jsPDF function, splitTextToSize(text, maxlen, options). This function returns an array of strings. Fortunately, the jsPDF text() function, which is used to write to the document, accepts both strings and arrays of strings.

var splitTitle = doc.splitTextToSize(reportTitle, 180);
doc.text(15, 20, splitTitle);
9
votes

Auto-paging and text wrap issue in JSPDF can achieve with following code

 var splitTitle = doc.splitTextToSize($('#textarea').val(), 270);
    var pageHeight = doc.internal.pageSize.height;
    doc.setFontType("normal");
    doc.setFontSize("11");
    var y = 7;
    for (var i = 0; i < splitTitle.length; i++) {                
        if (y > 280) {
            y = 10;
            doc.addPage();
        }
        doc.text(15, y, splitTitle[i]);
        y = y + 7;
    }
    doc.save('my.pdf');
3
votes

To wrap long string of text to page use this code:

var line = 25 // Line height to start text at
var lineHeight = 5
var leftMargin = 20
var wrapWidth = 180
var longString = 'Long text string goes here'

var splitText = doc.splitTextToSize(longString, wrapWidth)
for (var i = 0, length = splitText.length; i < length; i++) {
  // loop thru each line and increase
  doc.text(splitText[i], leftMargin, line)
  line = lineHeight + line
}
1
votes

If you need to dynamically add new lines you want to access the array returned by doc.splitTextToSize and then add more vertical space as you go through each line:

var y = 0, lengthOfPage = 500, text = [a bunch of text elements];

//looping thru each text item
for(var i = 0, textlength = text.length ; i < textlength ; i++) {

    var splitTitle = doc.splitTextToSize(text[i], lengthOfPage);

    //loop thru each line and output while increasing the vertical space
    for(var c = 0, stlength = splitTitle.length ; c < stlength ; c++){

        doc.text(y, 20, splitTitle[c]);
        y = y + 10;

    }

}
0
votes

Working Helper function

Here's a complete helper function based on the answers by @KB1788 and @user3749946:

It includes line wrap, page wrap, and some styling control:

(Gist available here)

function addWrappedText({text, textWidth, doc, fontSize = 10, fontType = 'normal', lineSpacing = 7, xPosition = 10, initialYPosition = 10, pageWrapInitialYPosition = 10}) {
  var textLines = doc.splitTextToSize(text, textWidth); // Split the text into lines
  var pageHeight = doc.internal.pageSize.height;        // Get page height, well use this for auto-paging
  doc.setFontType(fontType);
  doc.setFontSize(fontSize);

  var cursorY = initialYPosition;

  textLines.forEach(lineText => {
    if (cursorY > pageHeight) { // Auto-paging
      doc.addPage();
      cursorY = pageWrapInitialYPosition;
    }
    doc.text(xPosition, cursorY, lineText);
    cursorY += lineSpacing;
  })
}

Usage

// All values are jsPDF global units (default unit type is `px`)
const doc = new jsPDF();

addWrappedText({
  text: "'Twas brillig, and the slithy toves...", // Put a really long string here
  textWidth: 220,
  doc,

  // Optional
  fontSize: '12',
  fontType: 'normal',
  lineSpacing: 7,               // Space between lines
  xPosition: 10,                // Text offset from left of document
  initialYPosition: 30,         // Initial offset from top of document; set based on prior objects in document
  pageWrapInitialYPosition: 10  // Initial offset from top of document when page-wrapping
});  
0
votes

You can just use the optional argument maxWidth from the text function.

doc.text(15, 15, reportTitle, { maxWidth: 40 });

That will split the text once it reaches the maxWidth and start on the next line.

-1
votes

When we use linebreak in jsPDF we get an error stating b.match is not defined, to solve this error just unminify the js and replace b.match with String(b).match and u will get this error twice just replace both and then we get c.split is not defined just do the same in this case replace it with String(c).match and we are done. Now you can see line breaks in you pdf. Thank you