使用LitElement编写一个文档扫描的Web Component

Lit是一个用于构建快速轻量的Web Component的库。Lit的核心是一个用于编写组件的基类,它提供了响应性的状态、作用域内的样式和一个小巧的声明式模板系统。

在本文中,我们将使用LitElement编写一个Web Component,基于Dynamic Web TWAIN实现在浏览器中扫描文档。

新建项目

虽然Lit可以在没有构建系统的情况下使用,但在本文中,我们使用webpack (克隆下面的模板项目) :

bash 复制代码
git clone https://github.com/wbkd/webpack-starter

安装依赖项

  1. 安装Lit。

    bash 复制代码
    npm install lit
  2. 安装Dynamic Web TWAIN。

    bash 复制代码
    npm install dwt

    此外,我们需要将Dynamic Web TWAIN的资源文件复制到public文件夹中。

    1. 安装ncp

      bash 复制代码
      npm install --save-dev ncp
    2. 修改package.json的build和start命令以复制资源。

      diff 复制代码
       "scripts": {
         "lint": "npm run lint:styles; npm run lint:scripts",
         "lint:styles": "stylelint src",
         "lint:scripts": "eslint src",
         "build": "cross-env NODE_ENV=production webpack --config webpack/webpack.config.prod.js",
         "start": "webpack serve --config webpack/webpack.config.dev.js"
      +  "build": "ncp node_modules/dwt/dist public/dwt-resources && cross-env NODE_ENV=production webpack --config webpack/webpack.config.prod.js",
      +  "start": "ncp node_modules/dwt/dist public/dwt-resources && webpack serve --config webpack/webpack.config.dev.js"
       },
    3. 修改webpack.common.js以将public文件夹中的文件直接复制到输出文件夹,而不是输出文件夹中的public文件夹。

      diff 复制代码
       new CopyWebpackPlugin({
      -  patterns: [{ from: Path.resolve(__dirname, '../public'), to: 'public' }],
      +  patterns: [{ from: Path.resolve(__dirname, '../public'), to: '' }],
       }),

编写文档扫描组件

  1. 使用以下模板在src\scripts下创建新的documentscanner.js文件。

    js 复制代码
    import {LitElement, html, css} from 'lit';
    
    export class DocumentScanner extends LitElement {
      static properties = {
      };
      DWObject;
      static styles = css`
        :host {
          display: block;
        }
        `;
      constructor() {
        super();
      }
    
      render() {
        return html``;
      }
    }
    customElements.define('document-scanner', DocumentScanner);
  2. 添加一个div元素作为Dynamic Web TWAIN控件的容器(主要用于显示文档)。

    js 复制代码
    render() {
      return html`<div id="dwtcontrolContainer"></div>`;
    }
  3. constructor中配置Dynamic Web TWAIN。需要一个许可证来使用Dynamic Web TWAIN。可以在此处申请许可证。

    js 复制代码
    constructor() {
      super();
      Dynamsoft.DWT.AutoLoad = false;
      Dynamsoft.DWT.ResourcesPath = "/dwt/dist";
      Dynamsoft.DWT.ProductKey = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="; //one-day trial
    }
  4. 在DOM首次更新后的firstUpdated生命周期中初始化Dynamic Web TWAIN ,并将其绑定到上一步创建的容器。此外,发送一个自定义事件以发送Dynamic Web TWAIN的实例,这样我们可以在父元素中访问它。

    js 复制代码
    DWObject;
    firstUpdated() {
      let pThis = this;
      let dwtContainer = this.renderRoot.getElementById("dwtcontrolContainer");
      Dynamsoft.DWT.CreateDWTObjectEx(
        {
          WebTwainId: 'dwtcontrol'
        },
        function(obj) {
          pThis.DWObject = obj;
          pThis.DWObject.Viewer.bind(dwtContainer);
          pThis.DWObject.Viewer.show();
          pThis.DWObject.Viewer.width = "100%";
          pThis.DWObject.Viewer.height = "100%";
          const event = new CustomEvent('initialized', {
            detail: {
              DWObject: pThis.DWObject
            }
          });
          pThis.dispatchEvent(event);
        },
        function(err) {
          console.log(err);
        }
      );
    }
  5. 添加一个扫描文档的按钮和一个将文档图像保存为PDF文件的按钮。

    js 复制代码
    render() {
      return html`
      <div class="buttons">
        <button @click=${this.scan}>Scan</button>
        <button @click=${this.save}>Save</button>
      </div>
      <div id="dwtcontrolContainer"></div>`;
    }
    scan(){
      let pThis = this;
      if (pThis.DWObject) {
        pThis.DWObject.SelectSource(function () {
          pThis.DWObject.OpenSource();
          pThis.DWObject.AcquireImage();
        },
          function () {
            console.log("SelectSource failed!");
          }
        );
      }
    }
    
    save(){
      if (this.DWObject) {
        this.DWObject.SaveAllAsPDF("Scanned.pdf");
      }
    }
  6. 添加名为total的响应性属性,以反映扫描的文档页面数量。我们可以在Web TWAIN的OnBufferChanged事件中更新它的值。

    js 复制代码
    export class DocumentScanner extends LitElement {
      static properties = {
        total: {},
      };
      constructor() {
        super();
        this.total = 0;
        //...
      }
      render() {
        return html`
        <div class="buttons">
          <button @click=${this.scan}>Scan</button>
          <button @click=${this.save}>Save</button>
        </div>
        <div id="dwtcontrolContainer"></div>
        <div class="status">Total: ${this.total}</div>`;
      }
    
      firstUpdated() {
        //...
        Dynamsoft.DWT.CreateDWTObjectEx(
          {
            WebTwainId: 'dwtcontrol'
          },
          function(obj) {
            //...
            pThis.DWObject.RegisterEvent('OnBufferChanged',function () {
              pThis.total = pThis.DWObject.HowManyImagesInBuffer;
            });
            //...
          },
          function(err) {
            console.log(err);
          }
        );
      }
    }
  7. 设置组件的样式。

    js 复制代码
    static styles = css`
      :host {
        display: block;
      }
      .buttons {
        height: 25px;
      }
      #dwtcontrolContainer {
        width: 100%;
        height: calc(100% - 50px);
      }
      .status {
        height: 25px;
      }
      `;

使用文档扫描组件

  1. index.js文件中导入组件。

    js 复制代码
    import { DocumentScanner } from './documentscanner'; // eslint-disable-line
  2. index.html中添加组件。

    html 复制代码
    <document-scanner
      style="width:320px;height:480px;"
    ></document-scanner>

好了,我们现在可以从浏览器扫描文档了。

在线demo

源代码

欢迎下载源代码并尝试使用:

github.com/tony-xlh/do...

相关推荐
Boilermaker19922 分钟前
【Java EE】SpringIoC
前端·数据库·spring
中微子13 分钟前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上102428 分钟前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y44 分钟前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁1 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry1 小时前
Fetch 笔记
前端·javascript
拾光拾趣录1 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟1 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan1 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构