How to Scan and Upload Documents in Laravel Project

Laravel is a PHP Framework. This article shares how to use Dynamic Web TWAIN to scan and upload documents in a Laravel project.


Dynamic Web TWAIN for Laravel

Create a Laravel project skeleton:

composer create-project --prefer-dist laravel/laravel web-document-scan

Now let’s do something to Laravel controller, blade template and routes.


Create a controller:

php artisan make:controller DWTUploadController

The command will generate a new file - app\Http\Controllers\DWTUploadController.php. Add a page() function to render the blade template and add an upload() function to save uploaded files to images folder:


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Validator;

class DWTUploadController extends Controller
    function page()
     return view('dwt_upload');

    function upload(Request $request)
     $validation = Validator::make($request->all(), [
      'RemoteFile' => 'required'
      $image = $request->file('RemoteFile');
      $image->move(public_path('images'), $image->getClientOriginalName());
      return response()->json([
       'message'   => 'Successfully uploaded.'
      return response()->json([
       'message'   => $validation->errors()->all()


Create a blade template at resources\views\dwt_upload.blade.php. The template file contains all web front-end code.

<!DOCTYPE html>

    <title>Dynamic Web TWAIN for Laravel</title>
    <script src="{{ asset('Resources/dynamsoft.webtwain.initiate.js') }}" ></script>
    <script src="{{ asset('Resources/dynamsoft.webtwain.config.js') }}" ></script>
    <meta name="_token" content="{{csrf_token()}}" />

    <h3>Dynamic Web TWAIN for Laravel</h3>
    <div id="dwtcontrolContainer"></div>
    <input type="button" value="Load Image" onclick="loadImage();" />
    <input type="button" value="Scan Image" onclick="acquireImage();" />
    <input id="btnUpload" type="button" value="Upload Image" onclick="upload()">

        var DWObject;
        Dynamsoft.DWT.Containers = [{
            ContainerId: 'dwtcontrolContainer',
            Width: '480px',
            Height: '640px'
        Dynamsoft.DWT.RegisterEvent('OnWebTwainReady', Dynamsoft_OnReady);
        Dynamsoft.DWT.ProductKey = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";
        function Dynamsoft_OnReady() {
            DWObject = Dynamsoft.DWT.GetWebTwain('dwtcontrolContainer');
            var token = document.querySelector("meta[name='_token']").getAttribute("content");
            DWObject.SetHTTPFormField('_token', token);

        function loadImage() {
            var OnSuccess = function() {};
            var OnFailure = function(errorCode, errorString) {};
            if (DWObject) {
                DWObject.IfShowFileDialog = true;
                DWObject.LoadImageEx("", Dynamsoft.DWT.EnumDWT_ImageType.IT_ALL, OnSuccess, OnFailure);

        function acquireImage() {
            if (DWObject) {
                DWObject.IfShowUI = false;
                DWObject.IfDisableSourceAfterAcquire = true; 

        function upload() {
            var OnSuccess = function(httpResponse) {
                alert("Succesfully uploaded");

            var OnFailure = function(errorCode, errorString, httpResponse) {

            var date = new Date();
                "{{ route('dwtupload.upload') }}",
                date.getTime() + ".jpg",
                1, // JPEG
                OnSuccess, OnFailure



Note: you need to get a 30-day FREE Trial license of Dynamic Web TWAIN and update the license key:

Dynamsoft.DWT.ProductKey = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";


Add routes to routes\web.php:

Route::get('/dwt_upload', 'DWTUploadController@page');
Route::post('/dwt_upload/upload', 'DWTUploadController@upload')->name('dwtupload.upload');

Run the web server:

composer update
composer install
php artisan serve

Open in your web browser to have fun with the web document management application.

Laravel web document scan

Why Error Code?

419 status code

If you do not set CSRF token in header, you will fail to send the post request and get the 419 status code.

Laravel CSRF

500 status code

You may get the exception Symfony\Component\Mime\Exception\LogicException: Unable to guess the MIME type as no guessers are available (have you enable the php_fileinfo extension?)

Laravel php fileinfo extension

The workaround is to enable extension=fileinfo in the php.ini file.

php int extension


Source Code