Building a Web Document Scanning App with Node.js, Express, and Jade

Node.js, Express, and Jade are technologies often used together to build web applications. Node.js runs the server, handling HTTP requests and responses. Express is used to simplify the routing and middleware setup, managing everything from routes to handling requests and views. Jade is used as the templating engine within Express. It compiles templates into HTML that is sent to the client. In this article, we will demonstrate how to build a simple web document scanning application using Dynamic Web TWAIN, Node.js, Express, and Jade.

Prerequisites

Creating a Web Project with the Express Application Generator

Setting up a project with Express is straightforward:

  1. Install the Express generator globally using the following command:

     npm install express-generator -g
    
  2. Create a new project with the command below:

     express Dynamic-Web-TWAIN
    

    express generator

  3. Navigate to your project directory and install the necessary dependencies:

     cd Dynamic-Web-TWAIN
     npm install
    

Your simple web app is now ready. Start the server by running:

npm start

Then, open http://localhost:3000/ in your web browser to view the default page.

Integrating Dynamic Web TWAIN with Express and Jade

To begin, install the necessary packages, dwt for scanning documents and multer for handling file uploads:

npm install dwt multer --save
  • dwt: A Node.js module containing Dynamic Web TWAIN.
  • multer: A Node.js middleware for handling multipart/form-data, used for uploading files.

Configuring Static Resources

Configure the path for static resources in app.js to include the Dynamic Web TWAIN resources located in the node_modules folder:

const express = require('express');
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'node_modules/dwt/dist/')));

Updating Jade Templates

Include the Dynamic Web TWAIN JavaScript files in the views/layout.jade file:

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    script(src='dynamsoft.webtwain.min.js')
  body
    block content

In views/index.jade, initialize the Dynamic Web TWAIN object. Be sure to replace LICENSE-KEY with your actual license key:

script(type='text/javascript').
        var DWObject;
        window.onload = function () {
            if (Dynamsoft) {
                Dynamsoft.DWT.AutoLoad = false;
                Dynamsoft.DWT.UseLocalService = true;
                Dynamsoft.DWT.Containers = [{ ContainerId: 'dwtcontrolContainer', Width: '640px', Height: '640px' }];
                Dynamsoft.DWT.RegisterEvent('OnWebTwainReady', Dynamsoft_OnReady);
                // https://www.dynamsoft.com/customer/license/trialLicense?product=dwt
                Dynamsoft.DWT.ProductKey = 'LICENSE-KEY';
                Dynamsoft.DWT.ResourcesPath = '/';
                Dynamsoft.DWT.Load();
            }

        };

        function Dynamsoft_OnReady() {
            DWObject = Dynamsoft.DWT.GetWebTwain('dwtcontrolContainer'); 
        }

The ResourcesPath property specifies the path of dynamsoft.webtwain.min.js.

Designing the Layout

The layout is designed as follows:


extends layout
block content
  h1= title
  p Welcome to #{title}
  #dwtcontrolContainer
  input(
    type='button'
    value='Acquire'
    onclick='AcquireImage()'
  )
  input(
    id='btnUpload'
    type='button'
    value='Upload Image'
    onclick='btnUpload_onclick()'
  )
  • dwtcontrolContainer: An ID for a div element that contains the Dynamic Web TWAIN control.
  • Buttons for acquiring and uploading images.

Implement Button Click Events

The button click events are implemented as follows:

function AcquireImage() {
    if (DWObject) {
        DWObject.SelectSourceAsync().then(function () {
            return DWObject.AcquireImageAsync({
                IfCloseSourceAfterAcquire: true // Scanner source will be closed automatically after the scan.
            });
        }).catch(function (exp) {
            alert(exp.message);
        });
    }
}

function btnUpload_onclick() {
  if (DWObject) {
    DWObject.HTTPPort = 3000;
    var CurrentPathName = unescape(location.pathname); 
    var CurrentPath = CurrentPathName.substring(0, CurrentPathName.lastIndexOf("/") + 1);
    var strActionPage = CurrentPath + "upload";
    var strHostIP = "localhost";
    var sFun = function(){
        alert('successful');
    }, fFun = function(){

    };
    DWObject.HTTPUploadThroughPostEx(
        strHostIP,
        DWObject.CurrentImageIndexInBuffer,
        strActionPage,
        "test.jpg",
        1,// JPEG
    sFun, fFun
    );
  }
}

Handling File Uploads

To upload files, we need to automatically create an upload folder in the project root directory. Add the following code to app.js:

const fs = require('fs');
const uploadDir = path.join(__dirname, 'upload');

if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir);
}

Then create an upload.js file in the routes folder to handle POST requests:

var express = require('express');
var router = express.Router();
var multer = require('multer');

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './upload')
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname)
    }
})

const upload = multer({ storage: storage })

router.post('/', upload.single('RemoteFile'), function (req, res, next) {
    res.send();
});

module.exports = router;

Finally, import the upload module in app.js:

var upload = require('./routes/upload');
app.use('/upload', upload);

Starting the Server

Now, the application setup is complete. Run the server with:

npm start

Visit http://localhost:3000 in your web browser to see the application in action.

web document management with Dynamic Web TWAIN and Node.js Express

Source Code

https://github.com/yushulx/web-twain-document-scan-management/tree/main/examples/jade