Skip to content

JsPdf is saving a pdf but takes too long time to show it in google chrome #3137

Open
@stounej

Description

@stounej

I'm using JsPDF to download an html styled element, but when it is downloaded, it takes too long to be showed in google chrome as pdf (shows just an empty pdf document at first and charge it after long time),

the size of the file is only 300KB, I don't know why I have this problem however it's showed correctly in mozilla firefox browser

Please do you know how could I solve this problem.

this is my code

generatePDF = () => {
var doc = new jsPDF('p','pt',"a4");
const inp = document.getElementById("cv");
doc.html( inp , {
html2canvas: {
scale: 0.75,
},
callback: function (doc) {
var pageCount = doc.internal.getNumberOfPages();
doc.deletePage(pageCount)
doc.save("download.pdf");
}
});
}

this is the pdf file:
downloaded.pdf

Activity

HackbrettXXX

HackbrettXXX commented on Apr 20, 2021

@HackbrettXXX
Collaborator

Please attach the PDF document.

stounej

stounej commented on Apr 20, 2021

@stounej
Author

I have edited my post and included the pdf document, this is the code rendered in the pdf document:

import` '../App.css;
import personalInfo from '../Contexts/personalInfo';
import Grid from '@material-ui/core/Grid';
import {Typography} from '@material-ui/core';
import clsx from 'clsx';
import {makeStyles} from '@material-ui/core/styles';

const useStyles = makeStyles({
  paragraphes: {
    fontSize: "12px",
    overflow: "hidden",
    whiteSpace: "pre-wrap"
  },
  Typography: {
    textAlign: "center"
  },
  title: {
    fontSize: "20px",
    marginTop: "45px",
    textAlign: "center",
    fontFamily: "bold",
    backgroundColor: "#96b0bc",
    color: "white"
  },
  dates: {
    marginTop: "40px",
    fontSize: "12px",
    marginLeft: "13px"
  },
  h4: {
    fontSize: "15px",
    fontWeight: "bold",
    marginBottom: "8px",
    marginTop: "10px"
  }
});

//width: "21cm",height:"29.7cm"{width: "248.0px",height:"350.8px"
function PaperA4() {
  const classes = useStyles();
  return (
    <div class="page" data-size="A4" id="cv">
      <personalInfo.Consumer>
        {({
          fullname,
          email,
          phone,
          address,
          zip,
          city,
          country,
          driving,
          status,
          nationality
        }) => (
          <Grid container xs={12} direction="column" justify="center">
            <Grid
              item
              xs={12}
              justify="center"
              alignItems="center"
              style={{
              lineHeight: "5px",
              marginTop: "20px"
            }}>
              <Typography align="center" variant="h5">{fullname}</Typography>
            </Grid>
            <Grid item xs={12}>
              <Typography className={clsx(classes.Typography, classes.paragraphes)}>
                {email}&nbsp; {phone}&nbsp; {address}
                &nbsp; &nbsp; {city}
                &nbsp; {country}
                &nbsp; {nationality}
                &nbsp; {status}
                &nbsp; {zip}
                &nbsp;{driving}
              </Typography>
            </Grid>

          </Grid>
        )}
      </personalInfo.Consumer>
      <Grid container xs={12} direction="column" justify="center">
        <Typography className={classes.title} variant="h5">Professional Experience
        </Typography>
        <personalInfo.Consumer>
          {({experience}) => (experience.map((exp, i) => {
            return (
              <div key={i}>
                <Grid container xs={12} spacing={false}>
                  <Grid xs={3}>
                    <Typography className={classes.dates}>
                      {exp.startdate}-{exp.enddate}<br/> {exp.city},{exp.country}
                    </Typography>
                  </Grid>
                  <Grid xs={8}>
                    <Typography className={classes.paragraphes}>
                      <Typography className={classes.h4}>
                        {exp.job}
                        <br/> {exp.employer}
                      </Typography>
                      {exp.description}
                    </Typography>
                  </Grid>
                </Grid>
              </div>

            )
          }))}
        </personalInfo.Consumer>
      </Grid>
      <Typography className={classes.title} variant="h5">Education
      </Typography>
      <personalInfo.Consumer>
        {({education}) => (education.map((edu, i) => {
          return (
            <div key={i}>
              <Grid container xs={12} spacing={false}>
                <Grid xs={3}>
                  <Typography className={classes.dates}>
                    {edu.startdate}-{edu.enddate}<br/> {edu.city},{edu.country}
                  </Typography>
                </Grid>
                <Grid xs={8}>
                  <Typography className={classes.h4}>
                    {edu.degree}
                    <br/> {edu.school}
                  </Typography>
                  <Typography className={classes.paragraphes}>
                    {edu.description}
                  </Typography>
                </Grid>
              </Grid>
            </div>

          )
        }))}
      </personalInfo.Consumer>

    </div>

  );
}

export default PaperA4;`
HackbrettXXX

HackbrettXXX commented on Apr 22, 2021

@HackbrettXXX
Collaborator

The performance issue seems to be that each letter is written as a single chunk of text. Why that is, I don't know, yet.

stounej

stounej commented on Apr 22, 2021

@stounej
Author

I tried to transform the document to an Image before saving it and it worked but the text inside the pdf can't be copied,
I need the text to be copyable.

KurtGokhan

KurtGokhan commented on Jul 26, 2021

@KurtGokhan
Contributor

Seems like if there is letter-spacing in CSS, this will happen. Here is the workaround I am using to remove letter-spacing for PDF:

        onclone: async (d: HTMLDocument) => {
          const styleSheet = `
            * {
              letter-spacing: initial !important;
            }
          `;
          const style = document.createElement('style');
          style.innerText = styleSheet;
          d.head.appendChild(style);
        }
kevinmelo

kevinmelo commented on Sep 10, 2021

@kevinmelo

Any return? have the same issue

KurtGokhan

KurtGokhan commented on Oct 1, 2021

@KurtGokhan
Contributor

In addition to letter-spacing, too many words can also cause this issue. When letter-spacing is not 0, each letter is rendered separately. But when it is 0, html2canvas renders each word separately and that still makes the PDF size grow too much and cause performance problems.

I created this PR in html2canvas which significantly improves the performance by rendering multiple words in a line together.

4 remaining items

DanLopess

DanLopess commented on Dec 20, 2021

@DanLopess

@KurtGokhan Yeah unfortunately that wouldn't be ideal. However if I did that, since my HTML converts into multiple pages the image would have to be split (still haven't figured out how to do that) and I would have to calculate how many pages would be needed.

CollenZhou

CollenZhou commented on Jan 6, 2022

@CollenZhou

Hi dear authors any update?

CollenZhou

CollenZhou commented on Jan 7, 2022

@CollenZhou

Hi, just FYI. I noticed if a single table cell contains too much text will cause the performance issue. Hope it helps.

github-actions

github-actions commented on Apr 8, 2022

@github-actions

This issue is stale because it has been open 90 days with no activity. It will be closed soon. Please comment/reopen if this issue is still relevant.

prasheel888

prasheel888 commented on Oct 18, 2022

@prasheel888

Also having the same issue, Any Suggestions guys??

kevinmelo

kevinmelo commented on Oct 18, 2022

@kevinmelo

Also having the same issue, Any Suggestions guys??

At the end the best solution was using Puppeeter with my nodejs backend

prasheel888

prasheel888 commented on Oct 18, 2022

@prasheel888

Also having the same issue, Any Suggestions guys??

At the end the best solution was using Puppeeter with my nodejs backend

Thanks For Suggestion!!

haaah

haaah commented on Jan 3, 2024

@haaah

trying @KurtGokhan css hack does improve the rendering speed a little but when there's Word Starting With Upper Case it will sometimes join 2 word together --> WordWord.

Is there any other workaround ?

adamturski

adamturski commented on Feb 28, 2024

@adamturski

In my case generated PDF was loading fine in Ubuntu Document Viewer, but not in Chrome PDF viewer. Rendering was slow for some pages, visible especially on scrolling (but also on load if I put problematic element on first page). I could narrow down the issue to border-radius style on my table element. If text was short then there was no issue, but for long texts it was loading very long (forever). I set border-radius to 0 on my table container class and problem disappeared. I do not know why is that.
I also played with letter-spacing style and set 0 globally, but it helped just a little I would say - finally border-radius solved the issue.

Html:

<div id="exported-content">
        <div class="table-container">
        <table>
            <tr>
                <td>Test</td>
                <td>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                </td>
            </tr>
        </table>
        </div>
 </div>

Css:

.table-container {
    border-radius: 8px !important; // !!! This line was causing an issue with rendering PDF in Chrome.
    overflow: hidden;
    background-color: white;
}

JS:

new jsPDF({
            orientation: 'p',
            unit: 'mm',
            format: this.paperFormat,
            putOnlyUsedFonts: true,
            compress: true,
        }).html(document.getElementById('exported-content'), {
            html2canvas: {
                async: true,
                letterRendering: false,
                logging: true,
                removeContainer: true,
            },
            callback: (doc) => {
                doc.save("test.pdf");
            },
            margin: [15, 15, 15, 15],
            autoPaging: true,
            width: 180,
            windowWidth: 1080,
        });
Amatewasu

Amatewasu commented on Feb 28, 2024

@Amatewasu

@adamturski Thank you for the update. I just tested and I reproduce that removing the border radius in my generated pdf make them way faster in chrome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Amatewasu@adamturski@KurtGokhan@haaah@kevinmelo

        Issue actions

          JsPdf is saving a pdf but takes too long time to show it in google chrome · Issue #3137 · parallax/jsPDF