Error when using with Node.js: ReferenceError: canvas is not defined

Posted by: ken-sugiyama on 15 April 2024, 2:20 pm EST

    • Post Options:
    • Link

    Posted 15 April 2024, 2:20 pm EST

    Hello.

    I’m trying to get SpreadJS to work with Node.js.

    I referred to the sample provided in the following topic and tried to start SpreadJS version 17.0.5.

    https://developer.mescius.com/forums/spreadjs/referenceerror-self-is-not-defined

    However, I encountered the following error:

    ReferenceError: canvas is not defined

    It seems to work with version 16.0.4. Do you have any idea what might be causing this error?

  • Posted 15 April 2024, 9:58 pm EST

    Hi,

    The issue was caused because the Canvas was not defined. Refer to the below snippet to add canvas.

    const canvas = require("canvas");
    global.canvas = canvas;

    After adding the canvas, I encountered another error related to “Incorrect file format.” Upon investigation, I discovered that files were not importing correctly. Please refer to the following snippet to ensure files are imported correctly in a node environment.

    try {
    	var wb = new GC.Spread.Sheets.Workbook();
    	const data = fs.readFileSync('./export.sjs');
    	const blob = new Blob([data.buffer], { type: "application/zip" });
    	blob.name = "export.sjs";
    	blob.stream = fs.createReadStream('./export.sjs');
    	wb.open(blob, function () {
    		let sheet = wb.getActiveSheet();
    		console.log('-------load sjs file-------');
    		console.log(sheet.name());
    		console.log(sheet.getValue(3, 4));
    	}, function (e) {
    		console.log(e); // error callback
    	}, {
    		includeUnusedStyles: false
    	});
    
    	var wb1 = new GC.Spread.Sheets.Workbook();
    	const data1 = fs.readFileSync('./blank.xlsx');
    	const blob1 = new Blob([data1.buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
    	blob1.name = "blank.xlsx";
    	blob1.stream = fs.createReadStream('blank.xlsx');
    	wb1.import(blob1, function () {
    		console.log('-------load excel file---------');
    		let sheet = wb1.getActiveSheet();
    		console.log(sheet.name());
    		console.log(sheet.getArray(0, 0, 3, 1));
    	}, function (msg) {
    		console.log(msg); // error callback
    	}, {
    		fileType: GC.Spread.Sheets.FileType.excel,
    	});
    } catch (e) {
    	console.error("** Error manipulating spreadsheet **");
    	console.error(e);
    }

    I have created a sample for reference.

    Sample: nodeJs_sjs.zip

    Regards,

    Priyam

  • Posted 16 April 2024, 12:51 pm EST

    Hi, thank you!

    I’ve resolved the error and can now use SpreadJS with Node.js.

    Eventually, I plan to load a JSON of SpreadJS and export it as an Excel file.

    I’ve written the following code:

    const fs = require('fs');
    const mockBrowser = require('mock-browser').mocks.MockBrowser;
    const fileReader = require('filereader');
    const canvas = require("canvas");
    const { Blob } = require("buffer");
    
    global.window = mockBrowser.createWindow();
    global.document = window.document;
    global.navigator = window.navigator;
    global.self = global;
    global.HTMLCollection = window.HTMLCollection;
    global.getComputedStyle = window.getComputedStyle;
    global.FileReader = fileReader;
    global.canvas = canvas;
    
    const GC = require('@grapecity/spread-sheets');
    require('@grapecity/spread-sheets-io');
    
    const ExcelIO = require('@grapecity/spread-excelio');
    
    GC.Spread.Sheets.LicenseKey = "YourSpreadJSLicenseKeyHere";
    ExcelIO.LicenseKey = "YourExcelIOLicenseKeyHere";
    
    try {
        var wb = new GC.Spread.Sheets.Workbook();
        const data = fs.readFileSync('./export.sjs');
        const blob = new Blob([data.buffer], { type: "application/zip" });
        blob.name = "export.sjs";
        blob.stream = fs.createReadStream('./export.sjs');
        wb.open(blob, function () {
            let sheet = wb.getActiveSheet();
            console.log('-------load sjs file-------');
            console.log(sheet.name());
            console.log(sheet.getValue(3, 4));
        }, function (e) {
            console.log(e); // error callback
        }, {
            includeUnusedStyles: false
        });
    
        var wb1 = new GC.Spread.Sheets.Workbook();
        const data1 = fs.readFileSync('./blank.xlsx');
        const blob1 = new Blob([data1.buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
        blob1.name = "blank.xlsx";
        blob1.stream = fs.createReadStream('blank.xlsx');
        wb1.import(blob1, function () {
            console.log('-------load excel file---------');
            let sheet = wb1.getActiveSheet();
            console.log(sheet.name());
            console.log(sheet.getArray(0, 0, 3, 1));
            
            const json = wb1.toJSON();
            const spread = new GC.Spread.Sheets.Workbook();
            const excelIo = new ExcelIO.IO();
            spread.fromJSON(json);
    
            console.log('-------export excel file from JSON---------');
            excelIo.save(
                spread.toJSON(),
                (blob) => {
                    fs.appendFileSync('./export-from-json.xlsx', Buffer.from(blob));
                },
                (err) => {
                    logger.error(`Failed to output Excel file. ${err}`);
                },
                { useArrayBuffer: true },
            )
        }, function (msg) {
            console.log(msg); // error callback
        }, {
            fileType: GC.Spread.Sheets.FileType.excel,
        });
    } catch (e) {
        console.error("** Error manipulating spreadsheet **");
        console.error(e);
    }

    Excel file export succeeded. However, when blank.xlsx had images and text boxes pasted onto it, they were lost upon export. Do you have any idea what might be causing?

  • Posted 16 April 2024, 11:52 pm EST

    Hi,

    We are still investigating the issue at our end. We will let you know about our findings as soon as possible.

    Regards,

    Priyam

  • Posted 17 April 2024, 6:04 pm EST

    Hi,

    It seems like you haven’t imported the required dependencies in your application. Based on your code snippet that you have shared earlier, you are only using the following dependencies:

    @grapecity/spread-sheets
    @grapecity/spread-sheets-io
    @grapecity/spread-excelio

    However, in SpreadJS, the images are implemented as shapes and require you to add the shapes dependency in your application.

    Kindly try to add the following dependencies in your application:

    @grapecity/spread-sheets-shapes
    // For charts
    @grapecity/spread-sheets-charts

    Similarly, kindly add the required dependencies in your project.

    If the issue still persists for you, kindly do share a working sample along with the file that you are using so that we could investigate the issue at our end and could help you accordingly.

    Regards,

    Ankit

  • Posted 21 April 2024, 8:23 pm EST

    Hi,

    I apologize for the delay in responding.

    Thank you for your kind instruction. I will try following them to see if it works.

  • Posted 22 April 2024, 2:50 pm EST

    Hi,

    Kindly try at your end with the solution provided above. If the issue still persists for you, kindly do share a working sample along with the file that you are using so that we could investigate the issue at our end and could help you accordingly.

    Regards,

    Ankit

  • Posted 24 April 2024, 1:43 pm EST

    Hi,

    I tried the solution you provided and confirmed that it works without any issues.

    Thank you for your kind support this time! It was very helpful.

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels