How to zip React Spreadsheet data on the client side and send it to the server?
This knowledge base article explains how to zip the React Spreadsheet data on the client side and send it to the server. This can be achieved by compressing the spreadsheet JSON data using the pako library. Before sending it to the server, you need to trigger a custom save action on a button click by utilizing the saveAsJson method to save the spreadsheet data as JSON. Then, you can make a fetch call to the server as shown in the code snippet below.
[Client-Side]:
import { createRoot } from 'react-dom/client';
import './index.css';
import * as React from 'react';
import { SpreadsheetComponent, SheetsDirective, SheetDirective, ColumnsDirective, RangesDirective, RangeDirective, ColumnDirective } from '@syncfusion/ej2-react-spreadsheet';
import { defaultData } from './data';
import { createElement } from '@syncfusion/ej2-base';
import pako from 'pako';
const Default = () => {
let spreadsheet;
const customSave = () => {
spreadsheet.saveAsJson().then((response) => {
const jsonDataString = JSON.stringify(response.jsonObject.Workbook);
// Compress JSON data using Gzip
const compressedData = pako.gzip(jsonDataString, { level: 9 }); // 'pako' is a JavaScript library for data compression
const blob = new Blob([compressedData]);
let formData = new FormData();
formData.append('CompressedData', blob);
formData.append('FileName', 'Sample');
formData.append('SaveType', 'Xlsx');
formData.append('PdfLayoutSettings', JSON.stringify({ fitSheetOnOnePage: false, orientation: 'Portrait' })),
fetch(
'https://localhost:44354/api/spreadsheet/customSave',
{
method: 'POST',
body: formData,
}
).then((response) => {
response.blob().then((data) => {
let anchor = createElement('a', {
attrs: { download: 'Sample.xlsx' },
});
const url = URL.createObjectURL(data);
anchor.href = url;
document.body.appendChild(anchor);
anchor.click();
URL.revokeObjectURL(url);
document.body.removeChild(anchor);
});
});
});
}
return (<div className='control-pane'>
<div className='control-section spreadsheet-control'>
<button className="e-btn" onClick={customSave}>Custom save with compressed data</button>
<SpreadsheetComponent openUrl='https://localhost:44354/api/spreadsheet/open' saveUrl='https://localhost:44354/api/spreadsheet/save' ref={(ssObj) => { spreadsheet = ssObj; }}>
<SheetsDirective>
<SheetDirective name="Car Sales Report">
<RangesDirective>
<RangeDirective dataSource={defaultData}></RangeDirective>
</RangesDirective>
<ColumnsDirective>
<ColumnDirective width={180}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={180}></ColumnDirective>
<ColumnDirective width={130}></ColumnDirective>
<ColumnDirective width={120}></ColumnDirective>
</ColumnsDirective>
</SheetDirective>
</SheetsDirective>
</SpreadsheetComponent>
</div>
</div>);
}
export default Default;
const root = createRoot(document.getElementById('sample'));
root.render(<Default />);
On the server side, you need to define a custom class for SaveSettings to properly receive the compressed data. After receiving the data, decompress it using GZipStream and then convert it into a JSON string, as demonstrated in the code snippet below.
[Server-Side]:
namespace WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SpreadsheetController : ControllerBase
{
[HttpPost]
[Route("open")]
public IActionResult Open([FromForm]IFormCollection openRequest)
{
OpenRequest open = new OpenRequest();
open.File = openRequest.Files[0];
return Content(Workbook.Open(open));
}
[HttpPost]
[Route("save")]
public IActionResult Save([FromForm] SaveSettings saveSettings)
{
return Workbook.Save(saveSettings);
}
public class CustomSaveSettings
{
public IFormFile CompressedData { get; set; }
public string FileName { get; set; }
public SaveType SaveType { get; set; }
public string PdfLayoutSettings { get; set; }
}
[HttpPost]
[Route("customSave")]
public IActionResult CustomSave([FromForm] CustomSaveSettings saveSettings)
{
try
{
// Access the compressed data from the IFormFile
using (var stream = saveSettings.CompressedData.OpenReadStream())
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
byte[] compressedData = ms.ToArray();
// Decompress the received data using GZipStream
using (var compressedStream = new MemoryStream(compressedData))
using (var decompressedStream = new MemoryStream())
{
using (var gzipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
{
gzipStream.CopyTo(decompressedStream);
}
// Convert decompressed data to string
string jsonData = Encoding.UTF8.GetString(decompressedStream.ToArray());
// Create a new SaveSettings object
SaveSettings newSaveSettings = new SaveSettings
{
FileName = saveSettings.FileName,
JSONData = jsonData,
PdfLayoutSettings = saveSettings.PdfLayoutSettings,
SaveType = saveSettings.SaveType
};
// Call Workbook.Save method
return Workbook.Save(newSaveSettings);
}
}
}
catch (Exception ex)
{
// Handle any exceptions that may occur
return StatusCode(500, $"An error occurred: {ex.Message}");
}
}
}
}
Next, create a new SaveSettings object with all the required data and pass it to the Workbook.Save(newSaveSettings) method. Finally, you can save the response from the server’s save action as a downloadable Excel file.
Client-Side Sample: https://stackblitz.com/edit/react-qna6za-mqysfw?file=index.js
Server-Side Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/WebAPI1053547381
Note: Launch server-side sample before running the client-side sample.
Output:
You can find the Web API for Open/Save functionality at the location provided below.
Service sample Location: https://github.com/SyncfusionExamples/EJ2-Spreadsheet-WebServices/