Welcome Guest! To enable all features, please Login or Register.

Notification

Icon
Error

Options
View
Last Go to last post Unread Go to first unread post
#1 Posted : Thursday, August 24, 2017 1:41:24 PM(UTC)

Aaron  
Aaron

Groups: Registered, Tech Support, Administrators
Posts: 71

Was thanked: 3 time(s) in 3 post(s)

When using any browser based document viewers, one big issue is with large documents. Many times these documents take too much time to load due to their shear size. The LEADTOOLS HTML5 Document Viewer leverages a caching system to help elegantly load and save these documents.

In this post, we will discuss the bare minimum code used to get the LEADTOOLS version 19 HTML5 Document Viewer to load and save documents with their annotations to a cache file location.

By default, the back end web service of the LEADTOOLS HTML5 Document Viewer uses a cache system to automatically, save the loaded documents into the cache so the next time that document is loaded the load time is much faster. Below is a link to our documentation that discusses exactly how the LEADTOOLS HTML5 Document Viewer caching system works:

https://www.leadtools.co...s-documents-caching.html

For this post, we will be building off of our existing Tutorial1 HTML5 document viewer demo that can be found in the LEADTOOLS installation here:

<Install Directory>\LEADTOOLS 19\Examples\JS\Documents\DocumentViewer\DocumentViewer.sln

The Tutorial1 demo is a demo which contains the bare minimum code to get the HTML5 Document Viewer running properly.

Next we will need to add the annotations functionality to the Tutorial1 demo. The link below explains exactly how annotations work with the HTML5 Document Viewer and also contains sample source code for how to implement them:

https://www.leadtools.co...ntviewerannotations.html

For simplicity, I just added a drop down list to allow the user to select which annotations to draw. There were added to the index.html file of the Tutorial1 demo (<Install Directory>\LEADTOOLS 19\Examples\JS\Documents\DocumentViewer\Clients\Tutorials\Tutorial1\site\index.html):

Code:

<body>
   <div id="thumbnails"></div>
   <div id="documentViewer"></div>

   <div id="bottom-panel" style="height: 10%;">
      <button id="saveToCacheButton">Save to cache</button>
      <button id="loadFromCacheButton">Load from cache</button>
      <label for="annotationsSelect">Annotations objects:</label>
      <select id="annotationsSelect"></select>
   </div>
</body>


Now that we have the annotations working, we need to add the loading/saving from cache functionalities. These are done with the SaveToCache and LoadFromCache functionalities in the DocumentFactory of the JS files:

https://www.leadtools.co...factory-savetocache.html
https://www.leadtools.co...ctory-loadfromcache.html

The only thing you would need while using these functions is the name of the cache directory where the document was saved. You can get this DocumentID when the document is originally loading from the LoadFromUri function by getting the DocumentID property of the document object that is loaded:

https://www.leadtools.co...document-documentid.html

When calling SaveToCache, this DocumentID will be used for the cache directory.

When the documents and their annotations are saved to the cache, their contents are saved in .data and .json files. These are the files that will be used when we reload the document and its annotations from the cache.

A good practice is to call PrepareToSave on the document in the viewer before saving the document in any way. This is done to ensure any changes the user has made will be properly saved into the finalized document:

https://www.leadtools.co...iewer-preparetosave.html

At this point, you should have a working LEADTOOLS HTML5 Document Viewer with the ability to load a document, draw annotations on the document, save the document to cache, then reload that saved document.

Here is the updated app.ts Typescript file that you can copy and paste into your Tutorial1 demo (<Install Directory>\LEADTOOLS 19\Examples\JS\Documents\DocumentViewer\Clients\Tutorials\Tutorial1\ts) to see all this functionality (don't forget to add the new buttons and drop down list to the index.html file as mentioned above):

Code:

/*
 * NOTE for .js: The file you are vieweing has been compiled via Tutorial1TypeScript/app.ts.
 * If you do not want to use TypeScript, unload (or delete) the project or delete the app.ts file.
 */

var _documentViewer = null;
var _documentId = null;

window.onload = () => {
   // Create the options object for the DocumentViewer
   var createOptions: lt.Documents.UI.DocumentViewerCreateOptions = new lt.Documents.UI.DocumentViewerCreateOptions();

   // We will choose to use Elements Mode for this example, but you can disable it
   // Elements Mode can be styled with CSS - see the HTML for information
   createOptions.viewCreateOptions.useElements = true;
   createOptions.thumbnailsCreateOptions.useElements = true;

   //// Set thumbnailsContainer to #thumbnails
   createOptions.thumbnailsContainer = document.getElementById("thumbnails");
   // Set viewContainer to #documentViewer
   createOptions.viewContainer = document.getElementById("documentViewer");
   // Turn on annotation functionality
   createOptions.useAnnotations = true;

   // Create the document viewer
   _documentViewer = lt.Documents.UI.DocumentViewerFactory.createDocumentViewer(createOptions);

   // Set interactive mode to Pan / Zoom
   _documentViewer.commands.run(lt.Documents.UI.DocumentViewerCommands.interactivePanZoom);

   // We prefer SVG viewing over Image viewing for this example
   _documentViewer.view.preferredItemType = lt.Documents.UI.DocumentViewerItemType.svg;
   // To use Image: lt.Documents.UI.DocumentViewerItemType.image;

   // Change our thumbnails to be centered horizontally in the provided container
   _documentViewer.thumbnails.imageViewer.viewHorizontalAlignment = lt.Controls.ControlAlignment.center;

   // Before we call the service, we need to explain where it is ("localhost:19000/api", for example):
   lt.Documents.DocumentFactory.serviceHost = "http://localhost:19000"; // or wherever your host is
   lt.Documents.DocumentFactory.servicePath = ""; // the path to the root of the service, which is nothing for this example
   lt.Documents.DocumentFactory.serviceApiPath = "api"; // Routing occurs at "/api", unless you change the routing in the DocumentsService

   /* A quick example with a different service location:
    * > client: http://localhost:123
    * > service: https://www.leadtools.com/path/to/service
    * > service routing namespace: /api
    * 
    * Set these properties with these values:
    * serviceHost = "https://www.leadtools.com";
    * servicePath = "path/to/service";
    * serviceApiPath = "api"
    */

   // Load a PDF document
   var url = "https://demo.leadtools.com/images/pdf/leadtools.pdf";

   // Call the "LoadFromUri" and pass success and failure callbacks to the promise
   lt.Documents.DocumentFactory.loadFromUri(url, null)
      .done((document) => {
         // Set the document in the viewer
         _documentViewer.setDocument(document);
         // Keep track of the documentId (id used to save the document to the cache) so we can save/load the document to the cache later
         _documentId = document.documentId;
      })
      .fail((jqXHR, statusText, errorThrown) => {
         alert("Document Viewer Error - See console for details.");
      });

   /**********************************************************************************************************************/
   /* Below code shows the functionality for the following:                                                              */
   /* 1. How to add annotation functionality to the HTML5 Document Viewer                                                */
   /* 2. How to save the document in the viewer to cache after it has been modified                                      */
   /* 3. How to load an existing document into the viewer from the cache                                                 */
   /**********************************************************************************************************************/

   // The id's for the annotations objects so we can draw them 
   $("#annotationsSelect")
      .append($("<option>", { value: lt.Annotations.Core.AnnObject.selectObjectId })
         .text("Select"));

   $("#annotationsSelect")
      .append($("<option>", { value: lt.Annotations.Core.AnnObject.lineObjectId })
         .text("Line"));

   $("#annotationsSelect")
      .append($("<option>", { value: lt.Annotations.Core.AnnObject.rectangleObjectId })
         .text("Rectangle"));

   $("#annotationsSelect").on("change", function (e) {
      var objectid = parseInt($(this).find("option:selected").val());
      _documentViewer.annotations.automationManager.currentObjectId = objectid;
   });

   $("#saveToCacheButton").on("click", function () {
      _documentViewer.prepareToSave();
      var doc = _documentViewer.document;

      lt.Documents.DocumentFactory.saveToCache(doc)
         .done(function () {
            console.log('Document saved to cache with DocumentID: ' + _documentId);
         })
         .fail(function (jqXHR, statusText, errorThrown) {
            alert("Document Viewer Error - See console for details.");
         });
   });

   $("#loadFromCacheButton").on("click", function () {
      lt.Documents.DocumentFactory.loadFromCache(_documentId)
         .done(function (doc) {
            // Should have 5 pages and 2 documents (the PDF and the TIFF) 
            _documentViewer.setDocument(doc);
            console.log("Document (" + _documentId + ") loaded from cache");
         })
         .fail(function (jqXHR, statusText, errorThrown) {
            alert("Document Viewer Error - See console for details.");
         });
   });

   // Create html5 rendering engine 
   _documentViewer.annotations.automationManager.renderingEngine = new lt.Annotations.Rendering.AnnHtml5RenderingEngine();
   // Initialize documentViewer annotations 
   _documentViewer.annotations.initialize();
   // Handle what to do when current object Id changed 
   _documentViewer.annotations.automationManager.currentObjectIdChanged.add(function (sender, e) {
      // When done drawing, the manger will return to the select object; so we need force the annotationsSelect element to return to the select object option 
      $("#annotationsSelect option[value=" + sender.currentObjectId + "]").attr("selected", "selected");
   });
}


The best way to test the loading and saving from cache is to:
1. Run the application and let the default Leadtools.pdf file load into the viewer
2. Draw any annotation on the document in a particular location
3. Click the "Save to Cache" button to save the document to the cache.
4. Move the annotation somewhere else on the document or draw more annotations.
5. Click the "Load From Cache" button.
6. You should see the document load from the cache exactly as it was when you clicked the "Save to Cache" button.
Aaron Brasington
Developer Support Engineer
LEAD Technologies, Inc.

LEAD Logo
 

Try the latest version of LEADTOOLS for free for 60 days by downloading the evaluation: https://www.leadtools.com/downloads

Wanna join the discussion? Login to your LEADTOOLS Support accountor Register a new forum account.

You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2017, Yet Another Forum.NET
This page was generated in 0.241 seconds.