How XCEL Turns Excel Data Cleaning into a High‑Performance Cross‑Platform App
XCEL is a cross‑platform Excel data‑cleaning tool built with Electron and Vue that visualizes filtering, leverages multi‑process architecture, optimizes rendering and memory usage, and provides detailed implementation steps, performance tricks, and code examples for developers.
Project Background
Quantitative user‑research and lightweight data processing require data cleaning to remove outliers and ensure reliability. Manual cleaning lacks a unified, standardized workflow, so a visual, cross‑platform tool was created.
Key Features
Native‑like desktop experience built with Electron.
Visual Excel data manipulation with import/export support.
Three filter modes – single‑column, multi‑column, and dual‑range – combinable with AND, OR, and grouping.
Technical Stack
Electron – cross‑platform desktop framework (Windows 7+, macOS, Linux).
Vue full‑stack (Vue, Vuex, Vue‑router) – data‑driven UI.
js‑xlsx – pure‑JavaScript parser/generator for various spreadsheet formats.
Implementation Overview
Parse the uploaded Excel file with js‑xlsx to produce a JSON representation.
Apply user‑defined filter conditions to the JSON data.
Re‑structure the filtered data into the format required by js‑xlsx.
Generate a new Excel file from the transformed JSON.
Electron Deep Dive
Electron combines Chromium, Node.js, and native APIs to let developers write desktop apps with HTML, CSS, and JavaScript. It runs a main.js (main process) that controls the app lifecycle and creates one or more renderer processes (browser windows). Modules such as dialog are only usable in the main process, while renderer processes can access the full Node API.
Inter‑Process Communication (IPC)
IPC enables message passing between the main and renderer processes. The tool uses the main process as a hub: the UI renderer sends a filter‑start event, the main process forwards it to a background renderer, which performs heavy filtering and returns the result via filter‑response.
// UI renderer
ipcRenderer.send('filter-start', {filterTagList, filterWay, curActiveSheetName});
ipcRenderer.on('filter-response', (event, data) => { /* handle filtered data */ });
// Main process
ipcMain.on('filter-start', (e, args) => { backgroundWindow.webContents.send('filter-start', args); });
ipcMain.on('filter-response', (e, args) => { mainWindow.webContents.send('filter-response', args); });
// Background renderer
ipcRenderer.on('filter-start', (e, args) => { /* heavy computation */ ipcRenderer.send('filter-response', {filRow}); });Native Dialogs from Renderer
const { remote } = require('electron');
remote.dialog.showMessageBox({
type: 'question',
buttons: ['No', 'Yes'],
title: 'XCEL',
message: 'What is your dream?'
});Vue Considerations
Vue’s data‑driven view simplifies UI updates, but rendering 1913 × 180 cells (~340 k cells) with v‑for freezes the app. Two alternatives were evaluated:
Chunked push updates.
String concatenation followed by a single innerHTML insertion.
The second approach was chosen for its superior performance and simplicity, as it avoids Vue’s diffing overhead.
Additional Vue tips:
Disable Vuex strict mode in production to avoid deep‑watch overhead.
Freeze immutable data with Object.freeze() when possible.
Performance Optimizations
GPU Acceleration
Adding transform: translate3d(0,0,0) forces GPU rendering, smoothing scroll performance.
Memory Management
Heavy operations run in a background renderer, but IPC copies data, increasing memory usage. By storing the Excel JSON only in the background process and returning pre‑built HTML strings, memory consumption dropped by ~44 %.
Process Architecture
Electron’s multi‑process model (main + renderer + background renderer) isolates heavy computation, preventing UI freezes. The tool creates a single background process; scaling to CPU‑cores‑1 processes could further improve throughput.
Additional Technical Details
js‑xlsx supports reading XLSX, XLSB, XML SpreadsheetML, XLS, ODS, etc., and writing XLSX, CSV, JSON. Converting column indices beyond 26 requires a base‑26 conversion algorithm:
function getCharCol(n){let s='';while(n>0){let m=n%26+1;s=String.fromCharCode(m+64)+s;n=(n-m)/26;}return s;}
function getNumCol(s){if(!s) return 0;let n=0;for(let i=s.length-1,j=1;i>=0;i--,j*=26){let c=s[i].toUpperCase();if(c<'A'||c>'Z')return 0;n+=(c.charCodeAt()-64)*j-1;}return n;}Performance‑critical code was also refactored to avoid Object.assign() in favor of direct property assignment, yielding a noticeable speedup.
Conclusion
XCEL demonstrates how Electron and Vue can be combined to build a performant, cross‑platform Excel cleaning tool. By offloading heavy tasks to a background renderer, optimizing DOM updates, leveraging GPU acceleration, and carefully managing memory, the application achieves responsive UI even with large datasets.
Source code is available at https://github.com/o2team/xcel. Feedback via issues or pull requests is encouraged.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Aotu Lab
Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
