jsPDF icon indicating copy to clipboard operation
jsPDF copied to clipboard

Add support for svg element wen using jspdf html method

Open joseDaKing opened this issue 3 years ago • 9 comments

I think It would be nice if jspdf adds direct support for svg element when using HTML converter. I relay on ready icon components made of svg elements for my cv generator project. If I am honest with you I can live without this feature but it would make it easier for me and nicer to use this library.

joseDaKing avatar May 16 '21 20:05 joseDaKing

I'm already thinking about a way how that could work. Like detect the linked src or inpage SVG elements and convert them by canvg to png's before PDF generation. Another way could be by directly modify html2canvas to do that.

Androphin avatar Jan 02 '22 13:01 Androphin

I think adding this to html2canvas would be better. It would make html2canvas standalone better and we wouldn't have to implement some hacky workarounds in jsPDF.

HackbrettXXX avatar Jan 18 '22 11:01 HackbrettXXX

Managed to get SVG's to render using Canvg and patching the jspdf drawImage:

var ctx = pdf.canvas.getContext("2d");
const oldDrawImage = ctx.drawImage;
ctx.drawImage = (image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) => {
	const svgStartsWith = `data:image/svg+xml,`
	const isSvg = image.src.startsWith(svgStartsWith);
	if (isSvg) {
		const svgData = decodeURIComponent(image.src.split(svgStartsWith)[1]);
		ctx.save();
		ctx.translate(dx, dy);
		v = canvg.Canvg.fromString(ctx, svgData, {
			ignoreMouse: true,
			ignoreAnimation: true,
			ignoreDimensions: true,
			ignoreClear: true
		});

		v.start();
		ctx.restore();
	} else {
		oldDrawImage.call(ctx, image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
	}

	return ctx;
}

Contagious06 avatar Aug 19 '22 06:08 Contagious06

What's the work around ? I'm trying to implement a pdf renderer for a dynamic html page that may contain any number of SVG images mixed with text, tables etc... and I am struggling. Tried to implement @Contagious06 's solution with no luck.

If a kind soul could provide their implementation in a codepen, I would be very grateful.

bcdrme avatar Jan 14 '23 13:01 bcdrme

I also need this feature. In my case, I need to export an SVG based barcode generated by JsBarcode to PDF.

Using img or canvas works, but it's a little blurry.

risalfajar avatar Mar 03 '23 02:03 risalfajar

Any updates on this?

Intevel avatar Mar 17 '23 09:03 Intevel

Any updates on this?

My solution in this situaltion: I draw svg by svg2pdf.js 1.5.0 And draw text in blocks by pdf.text() Full code: https://gist.github.com/glebov21/cb4ca886de89970f77df2858b9fb93a8

let svgEl = drawdiv.children[1];
svg2pdf(svgEl, pdf, {
   xOffset: this.pdfPageDefaultOffsetX,
   yOffset: pdfOffsetY,
   scale: divToPdfRatio
});

for (let child of drawdiv.children) {
   if (child.tagName === 'DIV') {
      let divSelector = child.querySelector('div');
      if (divSelector) {
         let innerText = divSelector.textContent;
         if (innerText) {
            innerText = innerText.trim();
            let childSizes = child.getBoundingClientRect();
            ...pdf.text(this.pdfPageDefaultOffsetX + (child.offsetLeft * divToPdfRatio), textPositionTop, splitText, {
                  align: child.style.textAlign,
               });
         }
      }
   }
}

glebov21 avatar Mar 17 '23 11:03 glebov21

how would we handle svg that lie between a big react component?

thisisyashgarg avatar Jun 23 '23 14:06 thisisyashgarg

how would we handle svg that lie between a big react component?

Same question

sarmadzaki avatar Feb 21 '24 22:02 sarmadzaki