Blazor guidance request

Posted by: dev on 7 February 2021, 12:26 pm EST

    • Post Options:
    • Link

    Posted 7 February 2021, 12:26 pm EST

    Hello forum, I am about to integrate SpreadJS into an existing Blazor Webassembly app created using the Visual Studio 2019 templates. I have passed the sanity test of downloading a XLSX blob from a web service and loading and displaying the workbook in a SpreadJS component in a page.

    The Workbooks are created by data analysts in Excel and contain attractive dashboard style charts that are driven by ranges of numbers. There is a special sheet called “_config” which lists pairs of web service endpoints and cell ranges. In the next stage I must call each endpoint to get a matrix of numbers which are placed in a corresponding cell ranges to update the dashboard charts. In other words, the workbook contains instructions on how to update itself.

    Before I start on the next stage, I want to be sure I am following the best coding conventions for interacting with the SpreadJS component from C# code-behind. I need some general guidance.

    C# can only communicate with SpreadJS via JS-Interop, so I was prepared to create a suite of JS functions through which my C# code communicates with SpreadJS. This is rather verbose and fragile and I was wondering if there is some more robust or strongly-typed way of C# to SpreadJS communication.

    Any general advice on best practices would be most welcome.

    Thanks, Greg

  • Posted 7 February 2021, 10:48 pm EST

    Hi Greg,

    As you know that the SpreadJS is pure client-side control and interact with the JS methods. So your implementation is correct. Regarding the content update, you may trigger the APIs from C# and set the data by invoking the JS methods.

    Please refer to the attached sample for reference that Creates the Spread_Blazor component in a different project and you may use it in Blazor application.

    The sample is just for reference, please let us know if you have any issues or queries.

    Regards,

    Manish Gupta

    SpreadJS_Blazor_Lib.zip

  • Posted 14 February 2021, 10:22 am EST

    Thanks for confirming that using basic JS-interop is the only way for my Blazor app to communicate with the SpreadJS component.

    I have another question related to the asynchronous loading of a workbook. My C# code does an await call to invoke a function like this skeleton:

    
    function loadBook(xlsx) {
      var bytes = base64ToArrayBuffer(xlsx);
      var blob = new Blob([bytes], { ... });
      excelio.open(blob, function (json) {
        book.fromJSON(json);
      });
    }
    
    

    Immediately after the await call to this function my code makes another JS-interop call to get the names of the sheets, but all I get back is Sheet1 which indicates that the workbook has not been loaded yet, If I put a 300ms delay between the calls then I see all the sheets are now loaded.

    Clearly my C# await calls only waits on the outer function and it returns before the inner function with the fromJSON call has completed.

    What is the preferred technique for making the calling C# code async await the complete loading of the component? In other words, how can the C# code synchronise with the complete loading of the component?

  • Posted 14 February 2021, 12:06 pm EST

    I have one more question: Is there a way of getting the values of many cells in a single JS-Interop call?

    I need to get all of the values in a range like B11:C100 and making hundreds of calls in a loop to get the values seems rather inefficient.

  • Posted 15 February 2021, 4:49 pm EST

    Hi Greg,

    For calling other JS calls after an async JS calls, we need to return the promises from the JS Async calls. As the promise is returned by JS call, “await” waits to complete the first JS call before executing another JS call.

    Now you loadExcel would be as follows:

    
    function loadBook(xlsx) {
    return new Promise(function (resolve, reject) {
    
    var bytes = base64ToArrayBuffer(xlsx);
      var blob = new Blob([bytes], { ... });
      excelio.open(blob, function (json) {
        book.fromJSON(json);
        resolve("OK");
      },function(error){
    	reject("error")
      });
       });
    }
    
    

    Please refer to the attached sample for reference.

    For getting the values for Cells, you need to loop through. There is no any way to accomplish this.

    Regards,

    Manish Gupta

    Spread_asyncCall.zip

  • Posted 8 March 2021, 12:14 pm EST

    Thanks Manish for the detailed reply. I will incorporate your change into my app in coming days and I’m sure it will work (the sample works okay).

    Before your reply I found a workaround by making a callback from JS to C# when the from JSON completed. It’s not as elegant as a simple await, but it was only 4 extra lines of code and it works reliably.

    P.S. Would your developers consider adding an API call that retrieves a range of cells in one go? It would simplify my code, and I’m wondering if others would like it as well.

  • Posted 8 March 2021, 6:21 pm EST

    Hi Greg,

    As per our understanding, the await method should also be reliable. Also, we have requested from our concerned team for adding a method to returning the range of cells with the internal tracking id SJS-7895. We will let you know as we get an update on this.

    Regards,

    Manish Gupta

  • Posted 10 March 2021, 10:06 pm EST

    Hi Greg,

    We have a similar method named getArray() which returns the cell value in an array format.

    Please refer to the following documentation for reference:

    https://www.grapecity.com/spreadjs/docs/v14/online/SpreadJS~GC.Spread.Sheets.Worksheet~getArray.html?highlight=getarray%2C

    Regards,

    Manish Gupta

Need extra support?

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

Learn More

Forum Channels