Business central blog
Subscribe to blog and get news about new posts.

Full PDF Viewer for Business Central (PDFObject)

I have already wrote about PDF Viewer based on the PDF.js library. Now I want to talk about different solution based on PDF Object.

Agenda

PDFObject is a library that runs the standard built-in PDF renderer in the browser. This means that the rendering in different browsers may be different. This is a very interesting option for displaying PDFs in Business Central, as browser-based PDF Viewers often have powerful functionality.
After I have wrote an article about the Light PDF Viewer for Business Central (PDF.js), Dennis Reinecke(who is a very cool developer by the way) contacted me and told about another interesting way to render PDF in Business Central. Since he is a blogger, I waited until he prepared his version of the PDF Viewer on his blog. It uses a direct rendering PDF in iFrame. I decided to show you how to use PDFObject as this library uses an embeddable mechanism and contains all the necessary checks to see if your browser supports it.
Built-in PDF rendering in the browser has its pros and cons. The main problem is that we lose the ability to control the document programmatically, we can't change the way the browser renders or flip pages and etc. But at the same time we can be sure that the PDF is rendered as correctly as possible, and browsers often have good PDF renderers with all the necessary features.
So, we're going to declare ControlAddIn with the PDFObject library and our JS script with custom CSS:

controladdin "PDFV2 PDF Viewer"
{
    Scripts = 'https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js', 'https://unpkg.com/pdfobject@2.2.8/pdfobject.min.js', 'PDFViewer/script.js';
    StartupScript = 'PDFViewer/Startup.js';
    StyleSheets = 'PDFViewer/stylesheet.css';

    MinimumHeight = 400;
    MinimumWidth = 100;
    MaximumHeight = 2000;
    MaximumWidth = 4000;
    HorizontalStretch = true;
    VerticalStretch = true;
    VerticalShrink = true;
    HorizontalShrink = true;

    event ControlAddinReady();
    procedure LoadPDF(PDFDocument: Text; IsFactbox: Boolean)
    procedure SetVisible(IsVisible: Boolean)
}
Then we just initialize the control and set its style.

function InitializeControl(controlId) {
    var controlAddIn = document.getElementById(controlId);
    controlAddIn.innerHTML ='<div id="my-pdf"></div>';
}

function LoadPDF(PDFDocument,IsFactbox){
    var iframe = window.frameElement;

    requestAnimationFrame(() => {

        PDFObject.embed(PDFDocument, "#my-pdf");

        iframe.style.maxHeight = 1100 + 'px';
        iframe.style.height =  1100 + 'px';
    });
}



.pdfobject-container {
    max-width: 100%;
	max-height: 100%;
	height: 100%;
	border: 5px solid rgba(0,0,0,.2);
	margin: 0;
}
In order to view PDF in BC, I use a page that takes InStream and uploads the PDF as Base64.

page 81751 "PDFV2 PDF Viewer"
{
    Caption = 'PDF Viewer';
    PageType = Card;
    UsageCategory = None;
    layout
    {
        area(content)
        {
            group(General)
            {
                ShowCaption = false;
                usercontrol(PDFViewer; "PDFV2 PDF Viewer")
                {
                    ApplicationArea = All;

                    trigger ControlAddinReady()
                    begin
                        CurrPage.PDFViewer.LoadPDF(PDFAsTxt, false);
                    end;
                }
            }
        }
    }
    procedure SetPDFDocument(PDFInStream: InStream)
    var
        Base64Convert: Codeunit "Base64 Convert";
    begin
        PDFAsTxt := PDFAliasLbl + Base64Convert.ToBase64(PDFInStream);
    end;

    var
        PDFAsTxt: Text;
        PDFAliasLbl: Label 'data:application/pdf;base64,', Locked = true;
}
To test-drive the demo, go to Document Attachments of any source (Customer/Vendor/Document etc.)
Source code and application is available on github:
https://github.com/Drakonian/bc-pdf-viewer-full
August 2, 2022