Building a React Document Scanning Web App with Dynamic Web TWAIN SDK
In today’s digital age, efficient document management is crucial for businesses and individuals alike. Integrating document scanning capabilities directly into web applications can significantly streamline workflows, allowing users to digitize and manage documents with ease. In this tutorial, we’ll explore how to leverage the power of the Dynamic Web TWAIN SDK to create a React-based document scanning web app. This guide will walk you through the process of setting up a React project, integrating the SDK, and implementing features that enable users to scan, upload, and manage documents all within a user-friendly web interface.
Prerequisites
Steps to Build a React Document Scanning Web App
In the following sections, we’ll first create the foundational structure of a React project and then seamlessly integrate the Dynamic Web TWAIN SDK to enable robust document scanning and management capabilities.
Getting Started with a New React Project
To create a new React project, choose one of the following methods:
-
Using npm:
npm install -g create-react-app create-react-app document-scan
-
Using npx:
npx create-react-app document-scan
-
Using Yarn:
yarn create react-app document-scan
Integrating Document Scanning with Dynamic Web TWAIN SDK
First, install the required packages:
npm install dwt@latest
npm install @babel/core @babel/preset-env
npm i ncp -g
The Dynamic Web TWAIN SDK includes platform-specific service applications for scanner communication and JavaScript libraries, located in the node_modules/dwt/dist
folder. Use ncp
to copy these resources to the public
folder of your React project:
ncp node_modules/dwt/dist public/dwt-resources
Next, create a React component in DynamsoftSDK.js
:
import React from 'react';
import Dynamsoft from 'dwt';
export default class DWT extends React.Component {
constructor(props) {
super(props);
this.state = {
sourceList: [],
scanners: [],
currentScanner: "Looking for devices.."
};
this.selectRef = React.createRef();
}
DWObject = null;
containerId = 'dwtcontrolContainer';
width = "100%";
height = "600";
componentDidMount() {
Dynamsoft.DWT.RegisterEvent('OnWebTwainReady', () => {
this.DWObject = Dynamsoft.DWT.GetWebTwain(this.containerId);
if (this.DWObject) {
this.DWObject.GetDevicesAsync(Dynamsoft.DWT.EnumDWT_DeviceType.TWAINSCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.TWAINX64SCANNER).then((sources) => {
const sourceNames = sources.map(source => source.displayName);
this.setState({ scanners: sourceNames, sourceList: sources });
}).catch((error) => {
console.error("Error fetching devices:", error);
});
}
});
this.loadDWT();
}
loadDWT() {
Dynamsoft.DWT.ResourcesPath = "dwt-resources";
Dynamsoft.DWT.ProductKey = 'DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==';
Dynamsoft.DWT.Containers = [{ ContainerId: this.containerId, Width: this.width, Height: this.height }];
Dynamsoft.DWT.Load();
}
onSourceChange(value) {
this.setState({ currentScanner: value });
}
getSelectedIndex = () => {
const selectedIndex = this.selectRef.current.selectedIndex;
console.log("Selected Index:", selectedIndex);
return selectedIndex
}
acquireImage() {
const selectedIndex = this.selectRef.current.selectedIndex;
if (!this.state.sourceList || this.state.sourceList.length === 0) {
alert("No scanner detected. Please connect a scanner and try again.");
return;
}
this.DWObject.IfShowUI = false;
this.DWObject.SelectDeviceAsync(this.state.sourceList[selectedIndex]).then(() => {
return this.DWObject.OpenSourceAsync()
}).then(() => {
return this.DWObject.AcquireImageAsync({
IfDisableSourceAfterAcquire: true
})
}).then(() => {
if (this.DWObject) {
this.DWObject.CloseSource();
}
})
.catch(
(e) => {
console.error(e)
}
)
}
loadImagesOrPDFs() {
this.DWObject.IfShowFileDialog = true;
this.DWObject.Addon.PDF.SetResolution(200);
this.DWObject.Addon.PDF.SetConvertMode(1/*Dynamsoft.DWT.EnumDWT_ConvertMode.CM_RENDERALL*/);
this.DWObject.LoadImageEx("", 5 /*Dynamsoft.DWT.EnumDWT_ImageType.IT_ALL*/,
() => { },
(errorCode, errorString) => alert(errorString));
}
render() {
return (
<div style={{ width: "30%", margin: "0 auto" }}>
<select ref={this.selectRef} style={{ width: "100%" }} tabIndex="1" value={this.state.currentScanner} onChange={(e) => this.onSourceChange(e.target.value)}>
{
this.state.scanners.length > 0 ?
this.state.scanners.map((_name, _index) =>
<option value={_name} key={_index}>{_name}</option>
)
:
<option value="Looking for devices..">Looking for devices..</option>
}
</select>
<button tabIndex="2" style={{ marginRight: "4%", width: "48%" }}
onClick={() => this.acquireImage()}
disabled={this.state.scanners.length > 0 ? "" : "disabled"}
>Scan</button>
<button tabIndex="3" style={{ margin: "2% 0", width: "48%" }}
onClick={() => this.loadImagesOrPDFs()}
disabled={this.state.scanners.length > 0 ? "" : "disabled"}
>Load</button>
<div id={this.containerId}></div>
</div >
);
}
}
Explanation
Dynamsoft.DWT.ResourcesPath
: Specifies the path to the resources folder, located in the public directory.Dynamsoft.DWT.ProductKey
: Your license key for the Dynamic Web TWAIN SDK.onSourceChange
: Handles changes in the selected scanner.acquireImage
: Manages the document scanning process.loadImagesOrPDFs
: Allows users to load images or PDFs from the local file system.
Integrating the Component into App.js
Once your component is ready, integrate it into App.js
:
import logo from './logo.svg';
import DWTLogo from './icon-dwt.svg';
import DynamsoftLogo from './logo-dynamsoft-white-159X39.svg';
import './App.css';
import DWT from './DynamsoftSDK';
function App() {
return (
<div className="App">
<header className="App-header">
<a href="https://www.dynamsoft.com/web-twain/overview/" target="_blank" rel="noopener noreferrer" ><img src={DWTLogo} className="dwt-logo" alt="Dynamic Web TWAIN Logo" /></a>
<div style={{ width: "10px" }}></div>
<a href="https://reactjs.org/" target="_blank" rel="noopener noreferrer" ><img src={logo} className="App-logo" alt="logo" /></a>
<div style={{ width: "18%" }}></div>
<a href="https://www.dynamsoft.com" target="_blank" rel="noopener noreferrer" ><img src={DynamsoftLogo} className="ds-logo" alt="Dynamsoft Logo" /></a>
</header>
<main className="App-main">
<DWT
productKey="LICENSE-KEY"
/>
</main>
</div>
);
}
export default App;
Running the Application
Now that everything is set up, run the app with the following command:
npm start
This will launch the app in your default web browser, enabling document scanning and management directly within your React application.
Source Code
https://github.com/yushulx/web-twain-document-scan-management/tree/main/examples/react