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.js
Leadtools.Annotations.Designers.js
Leadtools.Annotations.Engine.js
Leadtools.Annotations.Rendering.JavaScript.js
Leadtools.js
Leadtools.Controls.js
Leadtools.Document.js
Leadtools.Document.Viewer.js
Make 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.ts
Leadtools.Annotations.Designers.d.ts
Leadtools.Annotations.Engine.d.ts
Leadtools.Controls.d.ts
Leadtools.d.ts
Leadtools.Document.d.ts
Leadtools.Document.Viewer.d.ts
These 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 viewer
private _documentViewer: lt.Document.Viewer.DocumentViewer = null;
// HTML Elements
public 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 visibility
let visibleThumbnails: boolean = window.getComputedStyle(this.thumbnailsContainer).display !== "none";
let visibleBookmarks: boolean = window.getComputedStyle(this.bookmarksContainer).display !== "none";
// Update navigationbar container top/bottom
this.navigationbarContainer.style.top = headerToolbarContainerHeight.toString() + "px";
this.navigationbarContainer.style.bottom = footerToolbarContainerHeight.toString() + "px";
// Update affected containers top/bottom
this.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 common
let containerWidth: number = parseInt(window.getComputedStyle(this.thumbnailsContainer).width);
// Now update viewer container
let imageViewerContainerDivLeft: number = navigationbarContainerWidth;
if (visibleThumbnails || visibleBookmarks)
imageViewerContainerDivLeft += containerWidth;
this.imageViewerContainerDiv.style.left = imageViewerContainerDivLeft.toString() + "px";
// The viewer container size might be changed; call onSizeChanged
this._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 Buttons
this.navigationbar.showThumbnailsBtn.addEventListener("click", () => this.showContainer(this.thumbnailsContainer, true));
this.navigationbar.showBookmarksBtn.addEventListener("click", () => this.showContainer(this.bookmarksContainer, true));
// Initialize the document viewer
this.initDocumentViewer();
// Initialize the UI
this.updateAppUIState();
// Verify Service Connection
lt.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 Document
const 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 containers
public showContainer(container, flipState: boolean): void {
let visibleThumbnails: boolean = window.getComputedStyle(this.thumbnailsContainer).display !== "none";
let visibleBookmarks: boolean = window.getComputedStyle(this.bookmarksContainer).display !== "none";
// Show Thumbnails
if (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 Bookmarks
if (container == this.bookmarksContainer) {
if (!visibleBookmarks) {
// Hide others
if (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 viewer
private initDocumentViewer(): void {
// Document Viewer Creation Options
let 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 displayed
createOptions.viewContainer = document.getElementById("imageViewerDiv");
// Set the UI part where the thumbnails are displayed
createOptions.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 viewer
try {
this._documentViewer = lt.Document.Viewer.DocumentViewerFactory.createDocumentViewer(createOptions);
// Document viewer settings
// SVG Preference for Display
this._documentViewer.view.preferredItemType = lt.Document.Viewer.DocumentViewerItemType.svg
// Lazy Loading
this._documentViewer.view.lazyLoad = true;
if (this._documentViewer.thumbnails)
this._documentViewer.thumbnails.lazyLoad = true;
// Log Rendering Errors
let 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 app
private 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 structure
if (document.structure.isParsed) {
this.finishSetDocument(document);
}
else
this.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 Image
this._documentViewer.view.useSvgBackImage = true;
}
// Set the loaded document in the document viewer
this._documentViewer.setDocument(document);
// Update the UI
this.updateAppUIState();
// Call onResize so the DIV sizes get updated
this.onResize(null);
// Fit page to display
this._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 license
var 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 license
if (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 App
let 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.