1

I'm working in an Angular project on Linux and the jsPDF library works great. The exported PDF right here, is exactly what I'm wanting/expecting to happen: Linux Export - good

I then launched the same code on both a Windows and Mac only to find that the resulting export is set to be at about 200% of what's expected as seen here: Windows/Mac Export - bad

I spent a great deal of time adjusting scaling, adding a scaled ratio to the end result, even got the first page looking correct, but then the second page onward got clipped starting exactly at the halfway point of the first page. Not to mention this fix then looked terrible back on the linux machine.

Any insight on why the rendering might be different between the machines? Has anyone else encountered this issue? Is it a known bug? Did something go over my head when reading about this library?

Here is the relative code of the export PDF function in my genreateReport.ts file:

declare global {
  interface Window { onePageCanvas: any; }
}

// hard coded for this question
totalPages = 39;

openPDF(): void {
const firstPage = document.getElementById(`uniqueName1`) as HTMLElement
const firstPageRect = firstPage.getBoundingClientRect();
const topBuffer1 = document.getElementById("noPrint") as HTMLDivElement
const bufferRect1 = topBuffer1.getBoundingClientRect()
const topBuffer2 = document.getElementById("banner") as HTMLDivElement
const bufferRect2 = topBuffer2.getBoundingClientRect()

let DATA: any = document.getElementById('htmlData');
html2canvas(DATA).then((canvas) => {
 const firstPageOr = (firstPageRect.width > firstPageRect.height) ? "l" : "p";

 var pdf = new jsPDF(firstPageOr, 'px', [firstPageRect.width, firstPageRect.height], true);

 for (var i = 0; i <= this.totalPages; i++) {
   const singlePage = document.getElementById(`uniqueName${i + 1}`) as HTMLElement;
   if (singlePage) {
      console.log(`Generating Page ${i + 1} / ${this.totalPages}`)

      const pageRect = singlePage.getBoundingClientRect();

         var srcImg  = canvas;
         var sX      = 0;
         var sY = pageRect.top - (bufferRect1.height + bufferRect2.height);
         var sWidth  = pageRect.width;
         var sHeight = pageRect.height;
         var dX      = 0;
         var dY      = 0;
         var dWidth  = sWidth;
         var dHeight = sHeight;

         window.onePageCanvas = document.createElement("canvas");
         window.onePageCanvas.setAttribute('width', sWidth);
         window.onePageCanvas.setAttribute('height', sHeight);

         var ctx = window.onePageCanvas.getContext('2d');
         ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);

         var canvasDataURL = window.onePageCanvas.toDataURL("image/png", 1.0);
             
         if (i > 0) {
            pdf.addPage([sWidth, sHeight], sWidth > sHeight? "l" : "p");
         }

         pdf.setPage(i+1);
         pdf.addImage(canvasDataURL, 'PNG', 0, 0, sWidth, sHeight);
    }
  }
 pdf.save('Test.pdf');
});
}

Here's the code of the generateReport.html file:

<div class="noPrint" id="noPrint">
  <button id="printButton" (click)="openPDF()" class="generateButton">Download PDF</button>
  <p style="display: none;" id="progress">
  </p>
</div>
<div id="htmlData" class="generalPage">
    <div *ngFor="let item of totalPages; index as i">
      <div class="reportPage" [id]="'uniqueName' + (i+1)">
        <div style="text-align: center;">
          <h3>Div/page {{i}}</h3>
        </div>
      </div>
    </div>
</div>

and some css if you really want to get fancy with it

.generalPage {
  width: 900px;
  margin: 0 auto;
}
.reportPage {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  width: 900px;
  font-size: large;
  padding: 1.2em;
  margin: 0 auto;
  border-radius: 20px;
  border-color: black;
  background-color: #d9d9d9;
  border-style: solid;
  border-width: 1px;
}
CJ Garcia
  • 11
  • 1

0 Answers0