skip to Main Content

I am trying to create an HTML web page that can convert a PDF file to JPG images and then export the rearranged pages as a new PDF file.

The codes are shown as follows:

<!DOCTYPE html>
<html>
  <head>
    <title>PDF pages rearranger</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
    <style>
      /* Define the style for the container element */
      #container {
        width: 600px;
        height: 400px;
        border: 1px solid black;
        margin: 20px auto;
        overflow: auto;
      }

      /* Define the style for the image elements */
      img {
        width: 100px;
        height: 100px;
        margin: 10px;
        cursor: move; /* Change the cursor to indicate that the images are draggable */
      }
    </style>

    <!-- Load the jQuery library from a CDN -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    <!-- Load the jQuery UI library from a CDN -->
    <script src="https://code.jquery.com/ui/1.13.0/jquery-ui.min.js"></script>

    <!-- Load the jsPDF library from a CDN -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
  </head>
  <body>
    <input type="file" id="fileInput" accept=".pdf" />
    <button id="convertButton">Convert to JPG</button>
    <!-- Create a div element to hold the images -->
    <div id="container"></div>
    <!-- Create a button to export the rearranged pages as a new PDF file -->
    <button id="exportButton">Export as PDF</button>

    <script>
      // Set the GlobalWorkerOptions.workerSrc property
      window.GlobalWorkerOptions = {
        workerSrc: 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js'
      };

      const fileInput = document.getElementById('fileInput');
      const convertButton = document.getElementById('convertButton');
      const container = document.getElementById('container');
      const exportButton = document.getElementById('exportButton');

      convertButton.addEventListener('click', async () => {
        const file = fileInput.files[0];
        if (!file) {
          alert('Please select a PDF file first');
          return;
        }

        // Clear any existing images in the container
        container.innerHTML = '';

        const reader = new FileReader();
        reader.onload = async (event) => {
          const typedArray = new Uint8Array(event.target.result);
          const pdfDocument = await pdfjsLib.getDocument(typedArray).promise;
          const numPages = pdfDocument.numPages;

          for (let i = 1; i <= numPages; i++) {
            const page = await pdfDocument.getPage(i);
            const viewport = page.getViewport({ scale: 1.0 });
            const canvas = document.createElement('canvas');
            canvas.width = viewport.width;
            canvas.height = viewport.height;
            const ctx = canvas.getContext('2d');
            await page.render({ canvasContext: ctx, viewport }).promise;
            const dataUrl = canvas.toDataURL('image/jpeg');
            download(dataUrl, `page${i}.jpg`);

            // Create an img element for each page and add it to the container
            const img = document.createElement('img');
            img.src = dataUrl;
            img.alt = `Page ${i}`;
            container.appendChild(img);
          }

          // Make the image elements draggable and sortable using jQuery UI
          $("#container").sortable({
            // Define a helper function to create a clone of the dragged image
            helper: function(e, ui) {
              return $(ui).clone().appendTo("#container").show();
            }
          });
        };
        reader.readAsArrayBuffer(file);
      });

      exportButton.addEventListener('click', () => {
        // Create a new jsPDF instance
        const doc = new jsPDF();

        // Get all the img elements in the container
        const images = container.querySelectorAll('img');

        // Add each image to the PDF document
        images.forEach((img, index) => {
          if (index > 0) {
            doc.addPage();
          }
          doc.addImage(img.src, 'JPEG', 10, 10);
        });

        // Save the PDF document
        doc.save('rearranged.pdf');
      });

      function download(dataUrl, filename) {
        const link = document.createElement('a');
        link.href = dataUrl;
        link.download = filename;
        link.click();
      }
    </script>
  </body>
</html>

However, when I tried to run the code, I encountered two issues:

The first warning message appears when I click the "Convert to JPG" button, saying “Deprecated API usage: No GlobalWorkerOptions.workerSrc specified.” I guess it is caused by the fact that the GlobalWorkerOptions.workerSrc property is not being set correctly.

The second warning message appears when I click the "Export as PDF" button, saying “Uncaught ReferenceError: jsPDF is not defined.” So seems the jsPDF library is not being loaded correctly.

Can anyone help me understand what might be causing these issues and provide suggestions for how to resolve them?

Edit:

With the help of @Alirahmon Nuraliev, my first problem is solved, but the second problem still remains unsolved, which is “Uncaught ReferenceError: jsPDF is not defined.”.

My rectified codes is as follows:

<!DOCTYPE html>
<html>
  <head>
    <title>PDF pages rearranger</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
    <style>
      /* Define the style for the container element */
      #container {
        width: 600px;
        height: 400px;
        border: 1px solid black;
        margin: 20px auto;
        overflow: auto;
      }

      /* Define the style for the image elements */
      img {
        width: 100px;
        height: 100px;
        margin: 10px;
        cursor: move; /* Change the cursor to indicate that the images are draggable */
      }
    </style>

    <!-- Load the jQuery library from a CDN -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    <!-- Load the jQuery UI library from a CDN -->
    <script src="https://code.jquery.com/ui/1.13.0/jquery-ui.min.js"></script>
  </head>
  <body>
    <input type="file" id="fileInput" accept=".pdf" />
    <button id="convertButton">Convert to JPG</button>
    <!-- Create a div element to hold the images -->
    <div id="container"></div>
    <!-- Create a button to export the rearranged pages as a new PDF file -->
    <button id="exportButton">Export as PDF</button>

    <script>
      // Set the GlobalWorkerOptions.workerSrc property
      const workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js';
      const pdfjsLib = window['pdfjs-dist/build/pdf'];
      pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;

      const fileInput = document.getElementById('fileInput');
      const convertButton = document.getElementById('convertButton');
      const container = document.getElementById('container');
      const exportButton = document.getElementById('exportButton');

      convertButton.addEventListener('click', async () => {
        const file = fileInput.files[0];
        if (!file) {
          alert('Please select a PDF file first');
          return;
        }

        // Clear any existing images in the container
        container.innerHTML = '';

        const reader = new FileReader();
        reader.onload = async (event) => {
          const typedArray = new Uint8Array(event.target.result);
          const pdfDocument = await pdfjsLib.getDocument(typedArray).promise;
          const numPages = pdfDocument.numPages;

          for (let i = 1; i <= numPages; i++) {
            const page = await pdfDocument.getPage(i);
            const viewport = page.getViewport({ scale: 1.0 });
            const canvas = document.createElement('canvas');
            canvas.width = viewport.width;
            canvas.height = viewport.height;
            const ctx = canvas.getContext('2d');
            await page.render({ canvasContext: ctx, viewport }).promise;
            const dataUrl = canvas.toDataURL('image/jpeg');
            download(dataUrl, `page${i}.jpg`);

            // Create an img element for each page and add it to the container
            const img = document.createElement('img');
            img.src = dataUrl;
            img.alt = `Page ${i}`;
            container.appendChild(img);
          }

          // Make the image elements draggable and sortable using jQuery UI
          $("#container").sortable({
            // Define a helper function to create a clone of the dragged image
            helper: function(e, ui) {
              return $(ui).clone().appendTo("#container").show();
            }
          });
        };
        reader.readAsArrayBuffer(file);
      });

      // Load jsPDF library and add event listener for export button
      const jsPDFScript = document.createElement('script');
      jsPDFScript.src =
        'https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js';
      jsPDFScript.onload = () => {
        exportButton.addEventListener('click', () => {
          // Create a new jsPDF instance
          const doc = new jsPDF();

          // Get all the img elements in the container
          const images = container.querySelectorAll('img');

          // Add each image to the PDF document
          images.forEach((img, index) => {
            if (index > 0) {
              doc.addPage();
            }
            doc.addImage(img.src, 'JPEG', 10, 10);
          });

          // Save the PDF document
          doc.save('rearranged.pdf');
        });
      };
      document.body.appendChild(jsPDFScript);

      function download(dataUrl, filename) {
        const link = document.createElement('a');
        link.href = dataUrl;
        link.download = filename;
        link.click();
      }
    </script>
  </body>
</html>

2

Answers


  1. The issues you’re facing are indeed related to the order of loading and potential timing issues with external libraries. Let’s address each issue separately:

    1. Deprecated API usage warning (GlobalWorkerOptions.workerSrc):
      To fix the "Deprecated API usage" warning, you need to set the GlobalWorkerOptions.workerSrc property after the pdf.js library has been loaded. You can achieve this by using the workerSrc option when initializing the pdfjsLib object. Place the following code at the beginning of your script:

      const workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js';
      const pdfjsLib = window['pdfjs-dist/build/pdf'];
      
      pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;
      

      Then, you can continue with the rest of your script as before.

    2. Uncaught ReferenceError: jsPDF is not defined:
      This error occurs because the jsPDF library is not being loaded or recognized. You need to ensure that the jsPDF library is fully loaded before you use it.

      To solve this issue, you can include your export code within an event listener for the jsPDF script’s load event. Here’s how you can do it:

      const jsPDFScript = document.createElement('script');
      jsPDFScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js';
      jsPDFScript.onload = () => {
        // Your export code here
        exportButton.addEventListener('click', () => {
          // ... (your existing export code)
        });
      };
      document.body.appendChild(jsPDFScript);
      

      Place this script after the section where you define the exportButton and the other elements.

    By addressing these two issues, your code should work as expected without warnings and errors. The key is to ensure that the required libraries are loaded and initialized in the correct order.

    Login or Signup to reply.
  2. Try this code

    <html>
      <head>
        <title>PDF pages rearranger</title>
        <style>
          /* Define the style for the container element */
          #container {
            width: 600px;
            height: 400px;
            border: 1px solid black;
            margin: 20px auto;
            overflow: auto;
          }
    
          /* Define the style for the image elements */
          img {
            width: 100px;
            height: 100px;
            margin: 10px;
            cursor: move; /* Change the cursor to indicate that the images are draggable */
          }
        </style>
    
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
    
        <!-- Load the jQuery library from a CDN -->
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    
        <!-- Load the jQuery UI library from a CDN -->
        <script src="https://code.jquery.com/ui/1.13.0/jquery-ui.min.js"></script>
      </head>
      <body>
        <input type="file" id="fileInput" accept=".pdf" />
        <button id="convertButton">Convert to JPG</button>
        <!-- Create a div element to hold the images -->
        <div id="container"></div>
        <!-- Create a button to export the rearranged pages as a new PDF file -->
        <button id="exportButton">Export as PDF</button>
    
        <script>
          // Set the GlobalWorkerOptions.workerSrc property
          const workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js';
          const pdfjsLib = window['pdfjs-dist/build/pdf'];
          pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;
    
          const fileInput = document.getElementById('fileInput');
          const convertButton = document.getElementById('convertButton');
          const container = document.getElementById('container');
          const exportButton = document.getElementById('exportButton');
    
          convertButton.addEventListener('click', async () => {
            const file = fileInput.files[0];
            if (!file) {
              alert('Please select a PDF file first');
              return;
            }
    
            // Clear any existing images in the container
            container.innerHTML = '';
    
            const reader = new FileReader();
            reader.onload = async event => {
              const typedArray = new Uint8Array(event.target.result);
              const pdfDocument = await pdfjsLib.getDocument(typedArray).promise;
              const numPages = pdfDocument.numPages;
    
              for (let i = 1; i <= numPages; i++) {
                const page = await pdfDocument.getPage(i);
                const viewport = page.getViewport({ scale: 1.0 });
                const canvas = document.createElement('canvas');
                canvas.width = viewport.width;
                canvas.height = viewport.height;
                const ctx = canvas.getContext('2d');
                await page.render({ canvasContext: ctx, viewport }).promise;
                const dataUrl = canvas.toDataURL('image/jpeg');
    
                // Create an img element for each page and add it to the container
                const img = document.createElement('img');
                img.src = dataUrl;
                img.alt = `Page ${i}`;
                container.appendChild(img);
              }
    
              // Make the image elements draggable and sortable using jQuery UI
              $('#container').sortable({
                // Define a helper function to create a clone of the dragged image
                helper: function (e, ui) {
                  return $(ui).clone().appendTo('#container').show();
                },
              });
            };
            reader.readAsArrayBuffer(file);
          });
    
          // Load jsPDF library and add event listener for export button
          const jsPDFScript = document.createElement('script');
          jsPDFScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js';
          jsPDFScript.onload = () => {
            const exportButton = document.getElementById('exportButton');
            exportButton.addEventListener('click', () => {
              // Create a new jsPDF instance
              window.jsPDF = window.jspdf.jsPDF; // Added with Nuraliev Alirahmon
              const doc = new jsPDF();
    
              // Get all the img elements in the container
              const images = container.querySelectorAll('img');
    
              // Add each image to the PDF document
              images.forEach((img, index) => {
                if (index > 0) {
                  doc.addPage();
                }
                doc.addImage(img.src, 'JPEG', 10, 10);
              });
    
              // Save the PDF document
              doc.save('rearranged.pdf');
            });
          };
          document.body.appendChild(jsPDFScript);
    
          function download(dataUrl, filename) {
            const link = document.createElement('a');
            link.href = dataUrl;
            link.download = filename;
            link.click();
          }
        </script>
      </body>
    </html>```
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search