jsPDF icon indicating copy to clipboard operation
jsPDF copied to clipboard

html: add width option

Open HackbrettXXX opened this issue 5 years ago • 16 comments

Currently, there is no easy way to specify the desired width of the html in the PDF. The width can only be specified indirectly over html2canvas' scale option (similar to #2917). It would be very convenient, if we could simply supply a width (in PDF units) to the html method. This option should basically function like the width of a browser window (which means, it should not scale the content).

HackbrettXXX avatar Sep 23 '20 15:09 HackbrettXXX

I can pick this up!

hmajid2301 avatar Sep 24 '20 09:09 hmajid2301

@hmajid2301 that would be really great!

One thought: the default value should be the width of the current page.

HackbrettXXX avatar Sep 24 '20 10:09 HackbrettXXX

Sorry I'm afraid I won't be able to pick this up any more.

Thanks

hmajid2301 avatar Sep 29 '20 00:09 hmajid2301

Hi there, I'm a first-time contributor, any chance I can work on this?

helpsdev avatar Oct 04 '20 01:10 helpsdev

can i take this?

rubiin avatar Oct 04 '20 20:10 rubiin

@helpsdev you can try ;) I'm assigning you for now.

@rubiin Maybe you two can collaborate?

HackbrettXXX avatar Oct 05 '20 09:10 HackbrettXXX

@HackbrettXXX any updates about this issue?

KamranMaqbool avatar Oct 07 '20 12:10 KamranMaqbool

@KamranMaqbool ask the two assignees ;)

HackbrettXXX avatar Oct 07 '20 14:10 HackbrettXXX

can i try this?

vbinithyanandamv avatar Dec 07 '20 06:12 vbinithyanandamv

Since the others didn't make a contribution, sure go ahead ;)

HackbrettXXX avatar Dec 07 '20 08:12 HackbrettXXX

@HackbrettXXX can you point some direction on this one?

vbinithyanandamv avatar Dec 09 '20 11:12 vbinithyanandamv

@vbinithyanandamv I would assume, we can just pass the correct width or windowWidth options to html2canvas. We probably need to consider the internal.scaleFactor to convert the PDF unit to pixels. I hope this does the trick. Maybe we also need to set the width of the canvas.js module.

HackbrettXXX avatar Dec 10 '20 09:12 HackbrettXXX

Updates?

richard-lopes-ifood avatar Jan 11 '21 17:01 richard-lopes-ifood

Here is how I did it. I am leveraging jQuery, so not sure how much you want to implement it.

    var pdf = new jspdf.jsPDF({
      orientation: "portrait",
      format: 'letter',
      customScaling:600/$($(".elementToPrint")[0]).width()
    });

Required adding a few lines in jsPDF.js right after the switch statement where you are checking what units are being used:

	if(options.customScaling){
		scaleFactor=options.customScaling;
	}

It will now dynamically scale to fit the width of your element.

ajhalls avatar Feb 10 '22 22:02 ajhalls

I would like something a bit more straight-forward but here is the solution I have: (I am also using jQuery for this test)

        const doc = new jsPDF("p", "pt", [500, 600]);
        const source = $("#element-to-print")[0];

        doc.html(
            source,
            {
                callback: (docWithHtml) => {
                    docWithHtml.save("Test.pdf")
                },
                width: 500,
                windowWidth: $(source).width()
            }
        );

This was inspired by the answer from @ajhalls. This makes the content scale to the width, however, I don't think this is a perfect solution since it leads to white space on the bottom of the page and it needs some tweaking, but it was the best way of allow my responsive components to fit on the page

Flavsditz avatar May 31 '22 08:05 Flavsditz

I wanted to share a second solution that I found. I wanted the PDF to have a precise size, and at this size, I had a perfect arrangement of my components. So what I did was to simply re-scale the container to the desired size, print, and erase that scaling. Since the change of the width happens as a style attribute on the tag, I simply remove the style tag, but it could be fine-tuned to just remove the attribute width I guess...

        const doc = new jsPDF("p", "pt", [500, 500]); //format: will take bigger as height, smaller as width IF on portrait mode (otherwise if on landscape)
        const source = $("#telement-to-print");

        source.innerWidth(500);

        doc.html(
            source[0],
            {
                callback: (docWithHtml) => {
                    docWithHtml.save("Test.pdf")

                    source.removeAttr("style");
                },
            }
        );

Flavsditz avatar Jun 09 '22 06:06 Flavsditz