[Special Summer Sale] 40% OFF All Magento 2 Themes

Cart

Recommended way to embed PDF in HTML?

  • This topic is empty.
Viewing 15 posts - 16 through 30 (of 30 total)
  • Author
    Posts
  • #9305
    monday
    Participant

    If you don’t want to host PDF.JS on your own, you could try DocDroid. It is similar to the Google Drive PDF viewer but allows custom branding.

    #9304
    wynn
    Participant

    I found this works just fine and the browser handles it in firefox. I have not checked IE…

    <script>window.location='url'</script>
    
    #9324
    astrophage
    Participant

    Our problem is that for legal reasons we are not allowed to temporarily store a PDF on the hard disk. In addition, the entire page should not be reloaded when displaying a PDF as Preview in the Browser.

    First we tried PDF.jS. It worked with Base64 in the viewer for Firefox and Chrome. However, it was unacceptably slow for our PDF. IE/Edge didn’t work at all.

    We therefore tried it with a Base64 string in an HTML object tag. This again didn’t work for IE/Edge (maybe the same problem as with PDF.js). In Chrome/Firefox/Safari again no problem.
    That’s why we chose a hybrid solution. Edge we use an IFrame and for all other browsers the object-tag.

    The IFrame solution would of course also work for Chrome and co. The reason why we didn’t use this solution for Chrome is that although the PDF is displayed correctly, Chrome makes a new request to the server as soon as you click on "download" in the preview. The required hidden-field pdfHelperTransferData (for sending our form data needed for PDF generation) is no longer set because the PDF is displayed in an IFrame. For this feature/bug see Chrome sends two requests when downloading a PDF (and cancels one of them).

    Now the problem children IE9 and IE10 remain. For these we gave up a preview solution and simply send the document by clicking the preview button as a download to the user (instead of the preview). We have tried a lot but even if we had found a solution the extra effort for this tiny part of users would not have been worth the effort. You can find our solution for the download here: Download PDF without refresh with IFrame.

    Our Javascript:

    var transferData = getFormAsJson()
    if (isMicrosoftBrowser()) {
            // Case IE / Edge (because doesn't recoginzie Pdf-Base64 use Iframe)
            var form = document.getElementById('pdf-helper-form');
            $("#pdfHelperTransferData").val(transferData);
            form.target = "iframe-pdf-shower";
            form.action = "serverSideFunctonWhichWritesPdfinResponse";
            form.submit();
     } else {
            // Case non IE use Object tag instead of iframe
            $.ajax({
                url: "serverSideFunctonWhichRetrivesPdfAsBase64",
                type: "post",
                data: { downloadHelperTransferData: transferData },
                success: function (result) {
                    $("#object-pdf-shower").attr("data", result);
                }
            })
     }
    
    

    Our HTML:

    <div id="pdf-helper-hidden-container" style="display:none">
       <form id="pdf-helper-form" method="post">
            <input type="hidden" name="pdfHelperTransferData" id="pdfHelperTransferData" />
       </form>
    </div>
    
    <div id="pdf-wrapper" class="modal-content">
        <iframe id="iframe-pdf-shower" name="iframe-pdf-shower"></iframe>
        <object id="object-pdf-shower" type="application/pdf"></object>
    </div>
    

    To check the browser type for IE/Edge see here: How can I detect Internet Explorer (IE) and Microsoft Edge using JavaScript? I hope these findings will save someone else the time.

    #9319
    despertaweb
    Participant

    This is the way I did with AXIOS and Vue.js:

            axios({
                url: `urltoPDFfile.pdf`,
                method: 'GET',
                headers: headers,
                responseType: 'blob'
            })
            .then((response) => {
                this.urlPdf = URL.createObjectURL(response.data)
            })
            .catch((error) => {
                console.log('ERROR   ', error)
            })
    

    add urlPDF dynamically to HTML:

    <object width='100%' height='600px' :data='urlPdf' type='application/pdf'></object>
    
    #9316
    fartwhif
    Participant
    1. Construct a blob of the input PDF bytes
    2. Use an iframe and PDF.js patched with this cross browser
      workaround

    The URI for the iframe should look something like this:

    /viewer.html?file=blob:19B579EA-5217-41C6-96E4-5D8DF5A5C70B
    

    Now FF, Chrome, IE 11, and Edge all display the PDF in a viewer in the iframe passed via standard blob URI in the URL.

    #9325
    ahmedakhtar11
    Participant

    You can use the relative location of the saved pdf like this:

    Example1

    <embed src="example.pdf" width="1000" height="800" frameborder="0" allowfullscreen>
    

    Example2

    <iframe src="example.pdf" style="width:1000px; height:800px;" frameborder="0" allowfullscreen></iframe>
    
    #9318
    pecata
    Participant

    I had to preview a PDF with React so after trying several libraries my optimal solution was to fetch the data and ebmed it.

    const pdfBase64 = //fetched from url or generated with jspdf or other library
    
      <embed
        src={pdfBase64}
        width="500"
        height="375"
        type="application/pdf"
      ></embed>
    
    #9309
    marc-partensky
    Participant

    I found that the best way to embed a pdf for my case was by using bootstrap because not only does it show the pdf but it also fill available space and you can specify the ratio as you wish. Here’s an example of what i made with it:

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
    
    <div class="embed-responsive embed-responsive-1by1">
      <iframe class="embed-responsive-item" src="http://example.com/the.pdf" type="application/pdf" allowfullscreen></iframe>
    </div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    #9310
    tony-bui
    Participant

    Before I got a problem with embeding base64 encoded with PDF because the URI limitation, so any files over 2MB won’t render properly on Chrome.

    My solution is:

    1. Convert uri encoded to Blob:

    2. Generate the temporary DOM String base on Blob.

      const blob = dataURItoBlob(this.dataUrl);

      var temp_url = window.URL.createObjectURL(blob);

    3. Decide where you want to attach the iframe to DOM:

      const target = document.querySelector(targetID);

      target.innerHTML = `<iframe src='${temp_url}' type="application/pdf"></iframe>

    #9307
    bob-singor
    Participant

    If you don’t want to host the PDFs yourself or want to customize your PDF viewer with additional security features like preventing users to download the PDF file. I recommend using CloudPDF. https://cloudpdf.io

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>CloudPDF Viewer</title>
      <style>
        body, html {
          height: 100%;
          margin: 0px;
        }
      </style>
    </head>
    <body style="height: 100%">
      <div id="viewer" style="width: 800px; height: 500px; margin: 80px auto;"></div>
      <script type="text/javascript" src="https://cloudpdf.io/viewer.min.js?version=0.1.0-beta.11"></script>
      <script>
        document.addEventListener('DOMContentLoaded', function(){
          const config = { 
            documentId: 'eee2079d-b0b6-4267-9812-b6b9eadb9c60',
            darkMode: true,
          };
          CloudPDF(config, document.getElementById('viewer')).then((instance) => {
    
          });
        });
      </script>
     </body>
    </html>
    
    #9308
    raoof
    Participant
    <embed src="data:application/pdf;base64,..."/>
    
    #9320
    nenad
    Participant

    Update – Adobe PDF Embed API

    Adobe released their Adobe PDF Embed API which is completely free. Since they created the PDF format itself, their API is probably the best for this.

    • It delivers the highest quality PDF rendering available.
    • You can fully customize user experience and choose how to display a PDF.
    • You will also have analytics on PDF usage so you can understand how users interact with PDFs, including time spent on a page and searches.

    All you have to do is create an api_key and use it in the code snippet.

    Displaying PDF by file_url

    Here is the example of the code snippet that you can just add to your HTML and take advantage of their API for displaying PDF by file_url. You would have to add { location: { url: "url_of_the_pdf" } } config.

    <div id="adobe-dc-view"></div>
    
    <script src="https://documentcloud.adobe.com/view-sdk/main.js"></script>
    
    <script type="text/javascript">
      document.addEventListener("adobe_dc_view_sdk.ready", function(){
        var adobeDCView = new AdobeDC.View({clientId: "api_key", divId: "adobe-dc-view"});
        adobeDCView.previewFile({
          content: { location: { url: "url_of_the_pdf" } },
          metaData: { fileName: "file_name_to_display" }
        }, {});
      });
    </script>
    

    Displaying PDF as buffer

    Here is the example of the code snippet that you can just add to your HTML and take advantage of their API for displaying PDF if you have the buffer (local file for example). You would have to add { promise: <FILE_PROMISE> } config.

    <div id="adobe-dc-view"></div>
    
    <script src="https://documentcloud.adobe.com/view-sdk/main.js"></script>
    
    <script type="text/javascript">
      document.addEventListener("adobe_dc_view_sdk.ready", function(){
        var adobeDCView = new AdobeDC.View({clientId: "api_key", divId: "adobe-dc-view"});
        adobeDCView.previewFile({
          content: { promise: <FILE_PROMISE> }
          metaData: { fileName: "file_name_to_display" }
        }, {});
      });
    </script>
    
    #9306
    khayri-r.r.-woulfe
    Participant

    Modern "full page screenshot" services or scripts nowadays are capable of producing long screenshots of full HTML and PDF pages and convert them into JPG or PNG files which can then be embedded as img element.

    #9311
    simon-fakir
    Participant

    I answered this question already somewhere else, however, I did an evaluation between multiple solutions. Also if you are planning for commercial use, these might be helpful:

    free solutions

    • iframe: Just use an iframe, however, this is not what most people search here.
    • [Google Docs Preview] Google docs has a preview (See other answer here)
    • Pdf.js is the open source solution without external dependencies
    • Adobe offers a ‘free’ PDF Embed API – recommended approach if you are okay with a cloud based solution.

    Commercial Providers

    • Pdf.js Express is commercialized extension to Pdf.js (worst performing product, not expensive)
    • PSPDFKit – Provder from Austria with rather good business support (moderate pricing, good product)
    • Foxit – Chinese company providing a PDF web solton as well. (cheapest commercial offer)
    • PDFTron – US-based competitor to PSDPDFkit ( more costly but also mot advanced)

    Hope this helps. I might publish more detailed information in a blogpost, if this is helping people (let me know in comments).

    #9312
    duc-trung-mai
    Participant

    Go with native solution if possible, it’s always the best solution as it comes natively from browser (using embed or iframe), or you can use this tiny lib to support you on that: https://pdfobject.com

    Most people recommend using PDF.JS which is famous. It has been working fine until I need to work with ShadowDOM. Some pages are in blank (white color), some in black color without any reason. Impossible for me to get to know what’s happening, and it’s in production :).

Viewing 15 posts - 16 through 30 (of 30 total)
  • You must be logged in to reply to this topic.