This tutorial shows how to create an ASP.NET Web application with TypeScript that uses the LEADTOOLS SDK to load a document in the HTML5 JavaScript Document Viewer.
| Overview | |
|---|---|
| Summary | This tutorial covers how to use LEADTOOLS Document Viewer SDK technology in an ASP.NET Web Application with TypeScript. |
| Completion Time | 45 minutes |
| Visual Studio Project | Download tutorial project (995 KB) |
| Platform | ASP.NET Web Application |
| IDE | Visual Studio 2022 |
| Runtime Target | .NET 6 or higher |
| Runtime License | Download LEADTOOLS |
| Try it in another language |
|
Get familiar with the basic steps of creating a project by reviewing the Add References and Set a License - ASP.NET and TypeScript tutorial, before working on the Display Files in the Document Viewer - ASP.NET and TypeScript tutorial.
Start with a copy of the project created in the Add References and Set a License - ASP.NET and TypeScript tutorial. If that project is unavailable, follow the steps in that tutorial to create it.
The references needed depend upon the purpose of the project. References can be added by .js files located at <INSTALL_DIR>\LEADTOOLS23\Bin\JS.
For this project, the following references are needed:
Leadtools.Annotations.Automation.jsLeadtools.Annotations.Designers.jsLeadtools.Annotations.Engine.jsLeadtools.Annotations.Rendering.JavaScript.jsLeadtools.jsLeadtools.Controls.jsLeadtools.Document.jsLeadtools.Document.Viewer.jsMake sure to add these files to the project's wwwroot\lib\leadtools folder. When adding these files in Visual Studio, other dependent JS files might be added as well. These can be removed if not listed above.
For a complete list of which JS files are required for your application, refer to Files to be Included with your Application
In addition, the following type definition files are needed for use with TypeScript:
Leadtools.Annotations.Automation.d.tsLeadtools.Annotations.Designers.d.tsLeadtools.Annotations.Engine.d.tsLeadtools.Controls.d.tsLeadtools.d.tsLeadtools.Document.d.tsLeadtools.Document.Viewer.d.tsThese can be found in the same folder as the .js files at <INSTALL_DIR>\LEADTOOLS23\Bin\JS
Make sure to copy these files to the project's scripts\leadtools folder.
The License unlocks the features needed for the project. It must be set before any toolkit function is called. For details including tutorials for different platforms, refer to Setting a Runtime License.
There are two types of runtime licenses:
Note
Adding LEADTOOLS references and setting a license are covered in more detail in the Add References and Set a License - ASP.NET and TypeScript tutorial.
With the project created, dependencies added, and the license set, coding can begin.
Open the Pages/index.chtml file located in the project folder. Add the following lines to import the JS files and attach the dependencies to the index.chtml page.
<!-- Leadtools .js files --><script src="~/lib/leadtools/Leadtools.js"></script><script src="~/lib/leadtools/Leadtools.Controls.js"></script><script src="~/lib/leadtools/Leadtools.Annotations.Engine.js"></script><script src="~/lib/leadtools/Leadtools.Annotations.Designers.js"></script><script src="~/lib/leadtools/Leadtools.Annotations.Rendering.JavaScript.js"></script><script src="~/lib/leadtools/Leadtools.Annotations.Automation.js"></script><script src="~/lib/leadtools/Leadtools.Document.js"></script><script src="~/lib/leadtools/Leadtools.Document.Viewer.js"></script><!-- DocumentViewer .js fies --><script src="~/js/app.js"></script>
Add the HTML elements that will be used as containers for the following components of the document viewer:
thumbnailsControl, which holds the thumbnails part of the document viewerbookmarksControl, which holds the bookmarks part of the document viewerimageViewerContainer, which holds the view part of the document viewerIn addition, add a navigationbar element that will contain buttons to toggle between the thumbnail and bookmark containers.
Replace the preexisting <div> element with the code below:
<div id="navigationbar" class="navigationbar"><button id="showThumbnails" class="navigationbarBtn"><span class="icon thumbnailsIcon"></span></button><button id="showBookmarks" class="navigationbarBtn"><span class="icon bookmarksIcon"></span></button></div><div id="thumbnailsControl" class="affectedContainers"><div class="controlHeader"><label>Pages</label></div><div id="thumbnails"></div></div><div id="bookmarksControl" class="affectedContainers"><div class="controlHeader"><label>Bookmarks</label></div><div id="bookmarks"></div></div><div id="imageViewerContainer" class="affectedContainers"><!-- The viewer will be dynamically created inside imageViewerDiv --><div id="imageViewerDiv"></div></div>
The affectedContainers class is used for selecting elements that will adjust their display according to the size of the browser window. The navigationbar class is used in a similar way to adjust the display of the imageViewerContainer when the bookmark or thumbnails controls are toggled.
Right-click on the wwwroot/cs folder from the project and choose Add -> New Item. Choose the Style Sheet File, type the name documentViewer.css for the filename, and click Add.
Use this file to specify the display styles for the HTML elements of the document viewer using the code below:
/* Document Viewer styles-------------------------------------------------- */body {height: 100%;background: white;overflow: hidden;color: #4D5F82;height: 100%;margin: 0;-webkit-text-size-adjust: none;font-family: helvetica;font-size: 10pt;margin-bottom: 60px;display: block;}.navigationbar {overflow: hidden;position: fixed;background-color: #DFE1E5;display: block;width: 40px;left: 0px;bottom: 60px;top: 57px;border-right: 1px solid;border-right-color: #D4D6DB;-webkit-box-shadow: 2px 0px 7px rgba(0, 0, 0, 0.3);box-shadow: 2px 0px 7px rgba(0, 0, 0, 0.3);z-index: 1;}.navigationbar .icon {width: 34px;}.navigationbarBtn {padding: 7px 0px 8px 0px;width: 100%;background-color: transparent;border: 1px solid transparent;border-right: 0;outline: none;width: 39px;height: 45px;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}.activeNavigationbarBtn {background-color: #D4D6DB;border-color: darkgray;}.icon {position: relative;display: inline-block;background-repeat: no-repeat;background-position: center;width: 35px;height: 25px;top: 3px;}.thumbnailsIcon {background-image: url("../resources/images/icons/Thumbnails.png");}.bookmarksIcon {background-image: url("../resources/images/icons/Bookmarks.png");}#imageViewerContainer {overflow: hidden;position: fixed;display: block;left: 0px;right: 0px;}#imageViewerDiv {position: relative;width: 100%;height: 100%;background-color: #C2C2C2;}#thumbnailsControl, #bookmarksControl {width: 195px;background-color: #D4D6DB;z-index: 1;position: fixed;left: 39px;-webkit-box-shadow: 5px 4px 5px -5px #333;box-shadow: 5px 4px 5px -5px #333;border: 1px solid darkgray;display: none;}#thumbnailsControl > .controlHeader, #bookmarksControl > .controlHeader {padding: inherit;text-align: inherit;padding-top: 13px;padding-left: 5px;}#thumbnails, #bookmarks {overflow: hidden;top: 43px;left: 5px;right: 5px;bottom: 5px;position: absolute !important;border: 1px solid darkgray;}#thumbnails {background-color: #fafdff;}#bookmarks {background-color: white;overflow: auto !important;font: normal normal 12px/20px Helvetica, Arial, sans-serif;}
Link this CSS file to be used in the Pages/index.chtml file:
<!-- DocumentViewer stylesheet --><link rel="stylesheet" href="~/css/documentviewer.css" />
In the Solution Explorer, open Program.cs and use the code below to configure the project entry point.
using Microsoft.AspNetCore.Builder;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;var builder = WebApplication.CreateBuilder(args);builder.Services.AddRazorPages();var app = builder.Build();if (app.Environment.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Error");app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapRazorPages();});app.Run();
The navigationbar element uses an icon image for each button contained for toggling the display of the thumbnail or bookmark containers.
Create a resources folder under the wwwroot node of the project then create the images\icons sub-folders.
Add the Bookmarks.png and Thumbnails.png icon images to this folder. These images can be found at <INSTALL_DIR>\LEADTOOLS23\Common\JS\Resources\Images\Icons
In the script\app.ts file, start by declaring a DocumentViewer module which will contain the existing window.onLoad function that sets the license.
Declare and export a new DocumentViewerApp class which will contain the properties and functions used for the configuration and operation of the document viewer web app.
Use the code below to define the public and private properties of the DocumentViewerApp as well as configure the constructor.
module DocumentViewer {export class DocumentViewerApp {// Document viewerprivate _documentViewer: lt.Document.Viewer.DocumentViewer = null;// HTML Elementspublic navigationbarContainer: HTMLElement = document.getElementById("navigationbar");public navigationbar = {showThumbnailsBtn: <HTMLButtonElement>document.getElementById("showThumbnails"),showBookmarksBtn: <HTMLButtonElement>document.getElementById("showBookmarks")};public imageViewerContainerDiv: HTMLElement = document.getElementById("imageViewerContainer");public thumbnailsContainer: HTMLElement = document.getElementById("thumbnailsControl");public bookmarksContainer: HTMLElement = document.getElementById("bookmarksControl");public affectedContainers: NodeListOf<HTMLElement> = document.querySelectorAll(".affectedContainers");constructor() {window.onunload = ((e: Event) => this.onUnload(e));window.onresize = ((e: Event) => this.onResize(e));}private onUnload(e: Event): void {if (this._documentViewer != null) {this._documentViewer.dispose();}}
Use the code below to dynamically update the display of the document viewer elements according to the browser window size in relation to the header and footer elements in the project.
This code also adjusts the display of the view container if the thumbnail or bookmark containers are visible.
private onResize(e: Event) {this.updateContainers();}public updateContainers(): void {let headerToolbarContainerHeight: number = document.querySelector<HTMLElement>(".navbar").offsetHeight;let footerToolbarContainerHeight: number = document.querySelector<HTMLElement>(".footer").offsetHeight;// Check visibilitylet visibleThumbnails: boolean = window.getComputedStyle(this.thumbnailsContainer).display !== "none";let visibleBookmarks: boolean = window.getComputedStyle(this.bookmarksContainer).display !== "none";// Update navigationbar container top/bottomthis.navigationbarContainer.style.top = headerToolbarContainerHeight.toString() + "px";this.navigationbarContainer.style.bottom = footerToolbarContainerHeight.toString() + "px";// Update affected containers top/bottomthis.affectedContainers.forEach(container => container.style.top = headerToolbarContainerHeight.toString() + "px");this.affectedContainers.forEach(container => container.style.bottom = footerToolbarContainerHeight.toString() + "px");let navigationbarContainerWidth: number = this.navigationbarContainer.offsetWidth;// Thumbnails, bookmarks and attachments Containers has same width// Use thumbnails container as commonlet containerWidth: number = parseInt(window.getComputedStyle(this.thumbnailsContainer).width);// Now update viewer containerlet imageViewerContainerDivLeft: number = navigationbarContainerWidth;if (visibleThumbnails || visibleBookmarks)imageViewerContainerDivLeft += containerWidth;this.imageViewerContainerDiv.style.left = imageViewerContainerDivLeft.toString() + "px";// The viewer container size might be changed; call onSizeChangedthis._documentViewer.view.imageViewer.onSizeChanged();if (this._documentViewer.thumbnails != null) {this._documentViewer.thumbnails.imageViewer.onSizeChanged();this._documentViewer.thumbnails.imageViewer.invalidate(lt.LeadRectD.empty);}}
Use the code below for the DocumentViewer.run() which will initialize the viewer, verify the service connection, and load a PDF document.
The PDF document that will be loaded is a sample Leadtools.pdf file that is available at https://demo.leadtools.com/images/pdf/leadtools.pdf
public run(): void {// Initialize the Navigation Bar Buttonsthis.navigationbar.showThumbnailsBtn.addEventListener("click", () => this.showContainer(this.thumbnailsContainer, true));this.navigationbar.showBookmarksBtn.addEventListener("click", () => this.showContainer(this.bookmarksContainer, true));// Initialize the document viewerthis.initDocumentViewer();// Initialize the UIthis.updateAppUIState();// Verify Service Connectionlt.Document.DocumentFactory.serviceHost = "http://localhost:40000";lt.Document.DocumentFactory.servicePath = "";lt.Document.DocumentFactory.serviceApiPath = "api";lt.Document.DocumentFactory.verifyService().done(() => {lt.LTHelper.log("Service connection verified!");}).fail(() => {lt.LTHelper.log("Service connection unavailable.");});// Load a Documentconst url = "https://demo.leadtools.com/images/pdf/leadtools.pdf";lt.Document.DocumentFactory.loadFromUri(url, null).done((doc) => {this.setDocument(doc);this.updateAppUIState();});}
Use the code below for the navigation bar buttons to use for controlling the visibility of the thumbnails and bookmarks containers.
// Toggle the visibility of the thumbnails/bookmarks containerspublic showContainer(container, flipState: boolean): void {let visibleThumbnails: boolean = window.getComputedStyle(this.thumbnailsContainer).display !== "none";let visibleBookmarks: boolean = window.getComputedStyle(this.bookmarksContainer).display !== "none";// Show Thumbnailsif (container == this.thumbnailsContainer) {if (!visibleThumbnails) {if (visibleBookmarks) {this.bookmarksContainer.style.display = "none";this.navigationbar.showBookmarksBtn.classList.remove("activeNavigationbarBtn");}this.navigationbar.showThumbnailsBtn.classList.add("activeNavigationbarBtn");this.thumbnailsContainer.style.display = "block";} else {if (flipState) {this.navigationbar.showThumbnailsBtn.classList.remove("activeNavigationbarBtn");this.thumbnailsContainer.style.display = "none";}}this.updateContainers();return;}// Show Bookmarksif (container == this.bookmarksContainer) {if (!visibleBookmarks) {// Hide othersif (visibleThumbnails) {this.thumbnailsContainer.style.display = "none";this.navigationbar.showThumbnailsBtn.classList.remove("activeNavigationbarBtn");}this.navigationbar.showBookmarksBtn.classList.add("activeNavigationbarBtn");this.bookmarksContainer.style.display = "block";} else {if (flipState) {this.navigationbar.showBookmarksBtn.classList.remove("activeNavigationbarBtn");this.bookmarksContainer.style.display = "none";}}this.updateContainers();return;}}
Use the following code to configure the document viewer. The createOptions object configures the creation of the viewer and hooks the HTML elements.
After the document viewer is created by the DocumentViewerFactory object, the document viewer settings can also be configured. In this tutorial, the following settings are applied:
// Create the document viewerprivate initDocumentViewer(): void {// Document Viewer Creation Optionslet createOptions: lt.Document.Viewer.DocumentViewerCreateOptions = new lt.Document.Viewer.DocumentViewerCreateOptions();createOptions.viewCreateOptions.useElements = false;createOptions.thumbnailsCreateOptions.useElements = false;// Set the UI part where the main view is displayedcreateOptions.viewContainer = document.getElementById("imageViewerDiv");// Set the UI part where the thumbnails are displayedcreateOptions.thumbnailsContainer = document.getElementById("thumbnails");// Set the UI part where the bookmarks are displayed (Set bookmarks container will show them in simple list)createOptions.bookmarksContainer = document.getElementById("bookmarks");createOptions.useAnnotations = false;// Create the viewertry {this._documentViewer = lt.Document.Viewer.DocumentViewerFactory.createDocumentViewer(createOptions);// Document viewer settings// SVG Preference for Displaythis._documentViewer.view.preferredItemType = lt.Document.Viewer.DocumentViewerItemType.svg// Lazy Loadingthis._documentViewer.view.lazyLoad = true;if (this._documentViewer.thumbnails)this._documentViewer.thumbnails.lazyLoad = true;// Log Rendering Errorslet imageViewer: lt.Controls.ImageViewer = this._documentViewer.view.imageViewer;let logRenderErrors: lt.Controls.ImageViewerRenderEventHandler = function (sender: any, e: lt.Controls.ImageViewerRenderEventArgs) {let item: number = e.item != null ? e.item.imageViewer.items.indexOf(e.item) : -1;let message: string = "Error during render item " + item + " part " + (e.part) + ": " + (e.error.message);lt.LTHelper.logError({ message: message, error: e.error });}imageViewer.renderError.add(logRenderErrors);if (this._documentViewer.thumbnails && this._documentViewer.thumbnails.imageViewer)this._documentViewer.thumbnails.imageViewer.renderError.add(logRenderErrors);}catch (e) {alert("DocumentViewer creation failed");lt.LTHelper.logError(e);return;}}
Use the code below to initialize the display of the document viewer app's user interface.
// Update the UI state of the appprivate updateAppUIState(): void {let hasDocument: boolean = this._documentViewer.hasDocument;if (hasDocument) {if (window.getComputedStyle(this.imageViewerContainerDiv).display === "none") {this.imageViewerContainerDiv.style.display = "block";this._documentViewer.view.imageViewer.updateTransform();}if (this.navigationbar.showThumbnailsBtn.matches(":disabled"))this.navigationbar.showThumbnailsBtn.disabled = false;if (this._documentViewer.document.isStructureSupported) {if (this.navigationbar.showBookmarksBtn.matches(":disabled"))this.navigationbar.showBookmarksBtn.disabled = false;} else {this.navigationbar.showBookmarksBtn.classList.remove("activeNavigationbarBtn");if (!(this.navigationbar.showBookmarksBtn.matches(":disabled")))this.navigationbar.showBookmarksBtn.disabled = true;if (this.bookmarksContainer.style.display === "block")this.bookmarksContainer.style.display = "none";}} else {if (window.getComputedStyle(this.imageViewerContainerDiv).display === "block") {this.imageViewerContainerDiv.style.display = "none";}this.navigationbar.showThumbnailsBtn.classList.remove("activeNavigationbarBtn");if (!(this.navigationbar.showThumbnailsBtn.matches(":disabled")))this.navigationbar.showThumbnailsBtn.disabled = true;if (this.thumbnailsContainer.style.display === "block")this.thumbnailsContainer.style.display = "none";this.navigationbar.showBookmarksBtn.classList.remove("activeNavigationbarBtn");if (!(this.navigationbar.showBookmarksBtn.matches(":disabled")))this.navigationbar.showBookmarksBtn.disabled = true;if (this.bookmarksContainer.style.display === "block")this.bookmarksContainer.style.display = "none";}this.updateContainers();}
The following code checks if the loaded document is parsed, parses the document if needed, and sets the loaded document into the document viewer.
public setDocument(document: lt.Document.LEADDocument): void {// See if we need to parse the document structureif (document.structure.isParsed) {this.finishSetDocument(document);}elsethis.parseStructure(document);}private parseStructure(document: lt.Document.LEADDocument): void {document.structure.parse().done((document: lt.Document.LEADDocument): void => {this.finishSetDocument(document);}).fail((): void => {lt.LTHelper.log("Error parsing the document structure.");});}public finishSetDocument(document: lt.Document.LEADDocument): void {if (this._documentViewer.view != null) {// Use SVG Back Imagethis._documentViewer.view.useSvgBackImage = true;}// Set the loaded document in the document viewerthis._documentViewer.setDocument(document);// Update the UIthis.updateAppUIState();// Call onResize so the DIV sizes get updatedthis.onResize(null);// Fit page to displaythis._documentViewer.commands.run(lt.Document.Viewer.DocumentViewerCommands.viewFitPage, null);}
Add a call to the run() method in the window.onLoad() function.
window.onload = () => {// If you have a JS license (LEADTOOLS.LIC.TXT) and key file (LEADTOOLS.LIC.KEY.TXT), you can use the code below to set your licensevar licenseUrl = "./lic/LEADTOOLS.lic.txt";var developerKey = "ADD THE CONTENTS OF YOUR LEADTOOLS.lic.key.txt FILE";// If you are evaluating and do not have a JS license or key file, you can use the code below to set your license://var licenseUrl = "https://demo.leadtools.com/licenses/js/LEADTOOLSEVAL.txt";//var developerKey = "EVAL";lt.RasterSupport.setLicenseUri(licenseUrl, developerKey, function (setLicenseResult) {// Check the status of the licenseif (setLicenseResult.result) {console.log("LEADTOOLS client license set successfully");} else {var msg = "LEADTOOLS License is missing, invalid or expired\nError:\n";console.log(msg);alert(msg);}});// Run the Document Viewer Applet app: DocumentViewerApp = new DocumentViewerApp();app.run();}
Before running the front-end Document Viewer, run the Document Service. The LEADTOOLS SDK installation provides three examples of the Document Service for the following platforms:
For instructions on how to set up and configure the Document Service, in the three platforms previously listed, refer to the steps in the Get Started with the Document Viewer Demo - HTML5 JavaScript tutorial.
For the purposes of this tutorial, the .NET Framework Document Service is used and it can be found here:
Once you have the back-end Document Service running, build and run the project in Visual Studio to host the web application on IIS Express with the selected browser.
The document viewer web application will run and load the sample PDF file. The thumbnails and bookmarks controls can be used to navigate the loaded document.

This tutorial showed how to initialize, load, and display a document in an ASP.NET TypeScript Document Viewer Web application.