当前位置:网站首页>Using webassembly to operate excel on the browser side
Using webassembly to operate excel on the browser side
2022-07-05 20:57:00 【Your menthol】
WebAssembly In fact, it has appeared for many years , It is a way to run assembly language in the browser virtual environment , The program it writes is called wasm.WebAssembly On 2015 First released in 2004 , The main goal is to make the execution speed of browsers catch up with that of native applications , At present, most browsers are enabled by default WebAssembly.
To write WebAssembly, You can use many languages , such as C,C++,RUST,.NET Other languages
Next I will demonstrate using C++ To develop a WebAssembly The whole process of the program .
Development system environment :ubuntu16
One 、WebAssembly The development process
1. Development environment installation
although WebAssembly It can be used C++ Development , But that doesn't mean , Use GCC, perhaps cl Wait for the program compiled by the compiler , It can run directly in the browser , To put C/C++ Or other languages to compile wasm file , Need to use other tools for translation . At present, the most standard tool is emscripten
emscripten install
emscripten This thing , It has strict requirements for the operating environment , therefore , The installation process should be operated in strict accordance with the official way
My development environment is ubuntu, stay ubuntu Installation on emscripten, First you have to install git, Has your system been installed git, On the terminal , Just execute it
git
If installed , The output content should be similar to that in the figure below 
If not , Just install one . although emscrpten It can also be in github Upload and download , However, it is recommended to install . Enter the following command , Just wait for the installation
sudo apt-get install git
installed git in the future , You can follow the official installation tutorial step by step
# from git download emsdk
git clone https://github.com/emscripten-core/emsdk.git
# Get into emsdk Catalog
cd emsdk
# Merge local code ( If you download it for the first time , Unwanted )
git pull
# Download and post the latest version
./emsdk install latest
# Set the latest version as the active version
./emsdk activate latest
# Set the environment variable
source ./emsdk_env.sh
The above steps are very important , Because there are few references at present , It is best to follow the above steps , If a step is performed incorrectly , It needs to be executed many times , Ensure that every step is completed
After the execution is completed, the emsdk Contents in folder , About the following

Then verify whether it is installed
emcc -v
Outputting the following content means that it is installed 
python install
python Is compiled WebAssembly The most important tool
at present emscripten Version required python, Is the need to python3.6 above , If you install 3.6 The following versions , Compilation will fail .
If you use it ubuntu It's also 16, Then the built-in of the system is python2, Cannot use now emscripten, To install python3.6 Version above
python3.6 It is recommended to use the source code for the installation of version , Because by apt-get, I didn't install it successfully
Go to python Official website download
https://www.python.org/downloads/source/

I downloaded it 3.6.9 If you're not sure , The same version I downloaded , Then perform decompression
tar -xvzf Python-3.6.9.tg
After decompression , Get into Python-3.6.9 Folder , And then execute
./configure
And then execute
make
make install
This starts the installation python3.6 了
After installation , Delete the original python2 link
rm -rf /usr/bin/python
Then python3 As the default link
ln -s ( Yours py3 Installation address ) /usr/bin/python
After all operations are completed , Direct knock in python, See if the operation is correct 
If you don't know just now python3 Where to install , Execute the following command to query , Then perform the above steps
whereis python3
cmake install
emscripten It can be executed cmake compile , If you want to compile some little things to play , Not really , However, it is recommended to install , If you make Use familiar words , You can also use make
You can see that you have installed cmake No, , Execute the following command
cmake

If installed , The output is probably like the above
without , Just apt-get install
apt-get install cmake
chrome browser
This is not necessary , except chrome browser ,edge etc. chrome The kernel browser is also ok ,firefox It's OK , But you installed chrome, At least 75 Later versions can
After the above things are installed , The basic development environment is complete
2. use WebAssembly operation excel
Let's write a WebAssembly operation excel Of documents demo
The complete code can be obtained at the following address
https://github.com/ltframe/code/tree/main/wasm-excel-demo
operation execl. I'm going to use C++ Compiling BasicExcel library , The reason for adopting this library is , Although it is not very powerful , But small enough , Easy to use , And there are few documents , The basic table operation has . I have written about its use before , You can turn it over
Goals achieved
1. Read out , And then in C++ In the middle of Json, Output to the front end , Then it is displayed by the front-end program
2. Modify the content at the front , Put the modified json Send back C++, Then generate a new file , Download to browser
BasicExcel Can only be opened xls file ,xlsx no way
establish excel file
Create a excel file , Get two worksheets inside ,
Then enter the content in the first worksheet 
Input a little in the second worksheet 
To write C++ file
class myclass
{
public:
wstring outputstr = L"";
myclass()
{
}
void saveexcel(string value)
{
cJSON *json = cJSON_Parse(value.c_str());
cJSON *info = cJSON_GetObjectItem(json, "info");
cJSON *count = cJSON_GetObjectItem(info, "count");
cJSON *tablenames = cJSON_GetObjectItem(info, "tablenames");
int _count = count->valueint;
cJSON *data = cJSON_GetObjectItem(json, "data");
BasicExcel *e = new BasicExcel();
e->New(_count);
for (int i = 0; i < 1; i++)
{
BasicExcelWorksheet* sheet = e->GetWorksheet((unsigned)i);
cJSON *name = cJSON_GetArrayItem(tablenames, i);
sheet->Rename(StringToWString(name->valuestring).c_str());
cJSON *list = cJSON_GetObjectItem(data, name->valuestring);
for (int j = 0; j < cJSON_GetArraySize(list); j++)
{
cJSON *item = cJSON_GetArrayItem(list,j);
for (size_t k = 0; k < cJSON_GetArraySize(item); k++)
{
cJSON *c = cJSON_GetArrayItem(item, k);
BasicExcelCell* cell = sheet->Cell(j, k);
cell->SetWString(StringToWString(c->valuestring).c_str());
}
}
}
e->SaveAs("/data/demo.xls");
}
void readsheet(BasicExcelWorksheet* sheet1)
{
size_t rows = sheet1->GetTotalRows();
size_t cols = sheet1->GetTotalCols();
for (size_t r = 0; r < rows; r++) {
outputstr+=L"[";
for (size_t c = 0; c < cols; c++)
{
BasicExcelCell* cell = sheet1->Cell(r, c);
// Determine the cell type
switch (cell->Type())
{
case BasicExcelCell::WSTRING:
{
const wchar_t* ret = cell->GetWString();
outputstr += L"\"";
outputstr += ret;
outputstr += L"\"";
if (c != cols - 1) {
outputstr += L",";
}
}
break;
default:
break;
}
}
outputstr+=L"]";
if(r!=rows-1){
outputstr+=L",";
}
}
}
wstring loadexcel(string fb)
{
outputstr += L"{\"info\":{";
BasicExcel *e =new BasicExcel;
wprintf(L"%ls\r\n",L"start load...");
string fname = string("/data/")+fb;
if (!e->Load(fname.c_str()))
{
wprintf(L"%ls\r\n",L"load failed");
return wstring(L"load failed\n");
}
int sheetscount = e->GetTotalWorkSheets();
outputstr +=L"\"count\":"+ std::to_wstring(sheetscount);
outputstr+=L",\"tablenames\":[";
for (size_t i = 0; i < sheetscount; i++)
{
outputstr+=L"\"";
outputstr+=e->GetUnicodeSheetName(i);
outputstr+=L"\"";
if(i!=sheetscount-1){
outputstr+=L",";
}
}
outputstr+=L"]},\"data\":{";
for (size_t i = 0; i < sheetscount; i++) {
BasicExcelWorksheet* sheet1 = e->GetWorksheet(i);
if (sheet1) {
outputstr += L"\"";
outputstr += e->GetUnicodeSheetName(i);
outputstr += L"\":[";
readsheet(sheet1);
outputstr += L"]";
if(i!=sheetscount-1){
outputstr += L",";
}
}
}
outputstr += L"}}";
wprintf(L"%ls",outputstr.c_str());
return outputstr;
}
};
EMSCRIPTEN_BINDINGS(myclass) {
class_<myclass>("myclass")
.constructor()
.function("loadexcel", &myclass::loadexcel)
.function("saveexcel", &myclass::saveexcel)
;
}
void setup_IDBFS(){
EM_ASM(
FS.mkdir('/data');
FS.mount(IDBFS,{
},'/data');
);
}
int main()
{
setup_IDBFS();
setlocale(LC_ALL, "chs");
return 0;
}
BasicExcel Don't use it , If you want to know , You can read my previous articles .
Mainly about emscripten The relevant part
EMSCRIPTEN_BINDINGS The function of is to establish a C++ Classes and JS Binding between classes , After binding , reception js In the code , It can be like using a js Class
function(“loadexcel”, &myclass::loadexcel), intend , Export this function to the foreground JS Use , The first parameter , Is in JS The name of the calling method in , The second parameter is your C++ Member function reference
EM_ASM(
FS.mkdir('/data');
FS.mount(IDBFS,{
},'/data');
);
This code represents creating a virtual data Folder , Then mount him to IDBFS In the system , Later on excel File operations are all in this folder
setup_IDBFS Function function , Is to build a file system , use IDBFS The path to mount the virtual file . because WebAssembly After all, it still runs in a virtual system , It is impossible to access your hard disk system , therefore setup_IDBFS, Meaning establishes a JS File system and yours C++ Code file system bridge .
except IDBFS, There are other file systems , The usage scenarios of each file system are different . You can go to the tutorial by yourself
To write cmake
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(cx)
AUX_SOURCE_DIRECTORY(. DIR_SOURCE)
SET(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
SET(CMAKE_C_COMPILER emcc)
SET(CMAKE_CPP_COMPILER 'em++')
set(CMAKE_CXX_FLAGS "--bind")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='[FS]' -s INITIAL_MEMORY=268435456 \
-s ASSERTIONS=1 \
-s STACK_OVERFLOW_CHECK=2 \
-s PTHREAD_POOL_SIZE_STRICT=2 \
-s ALLOW_MEMORY_GROWTH=1 \
-lidbfs.js")
ADD_EXECUTABLE(app ${DIR_SOURCE})
If the CMAKE If you don't know much , You can look at the documentation first , Have a brief understanding of cmake.
set(CMAKE_CXX_FLAGS "--bind")
Indicates that you want to enable the binding function , Namely c++ It's written in English EMSCRIPTEN_BINDINGS
CMAKE_EXE_LINKER_FLAGS In the options lidbfs.js, To use IDBFS File mode
EXTRA_EXPORTED_RUNTIME_METHODS Indicates that you want to export FS File system foreground use
such ,C++ Part is finished , So I started compiling ,
stay C++ Execute the following command in the project folder ,
mkdir build
Get into build Folder , perform
emcmake cmake ..

The output is roughly as shown in the figure above
After execution , And that's what happened app.js app.wasm Two documents , This is your c++ Compiled file ,app.wasm yes c++ Compiled file ,app.js It's a file like glue , Take yours. wasm and Js Documents are linked together , Of course, it's OK without this , You can also write the calling module yourself 
To write javascript
This should be relatively simple , This paragraph only posts the core part of the operation . Other parts are omitted
function writefile(e){
let result=reader.result;
const uint8_view = new Uint8Array(result);
FS.writeFile('/data/'+file.name, uint8_view)
}
function savetodisk()
{
var data=FS.readFile("/data/demo.xls");
var blob;
blob = new Blob([data.buffer], {
type: "application/vnd.ms-excel"});
saveAs(blob, "demo.xls");
}
function myfun(e) {
let files = document.getElementById('file').files;
file=files[0];
reader.addEventListener('loadend', writefile);
reader.readAsArrayBuffer(file);
setTimeout(()=>{
let jsonstr = instance.loadexcel(file.name);
//code......
},1000)
}
writefile Function functions , Open local excel file , In the virtual path /data/ among , Create a file , such C++ You can read it in , there data Namely C++ In file setup_IDBFS Created folder
savetodisk Is from the virtual file path , Read demo.xls file , Then download it on the browser , This demo.xls Is in C++ In file saveexcel Function created
To write HTML
This is much simpler , The code is not posted , The main thing is to put what you just generated app.js Just introduce ,wasm No need to introduce ,app.js Will load it
<script type="text/javascript" src="app.js" async></script>
Run the program
wasm The file cannot be opened and run directly , So you need a server to run , I'm going to use anywhere, Use other iis,apache Fine
The operation interface is as follows 
Open the debugging tool , The Internet ->wasm, You can see app.wasm Already loaded 
Next you can open excel The file , Click Select , Select the first step to create excel file , determine 
Display content , Namely excel The content of the document
Then casually change the contents of the cell 
Point save 
Prompt to download new files , Download and open 
It's the content just changed
Here we are , All functions have been developed
The complete source code and demo code can be downloaded from the following address
https://github.com/ltframe/code/tree/main/wasm-excel-demo
Two 、WebAssembly The future of
WebAssembly In terms of speed , Do than Javascript A lot of improvement , In addition, there are many libraries written in the underlying language , So that makes web The function of the application has been improved a lot , For example, if we usually want to read excel Words , The general practice is to excel Upload to server , Then the server parses , Back to the front end , There is now a wasm This way, , It can be done at the front end , In this way, the pressure on the server is much less .
also , Functions that cannot be realized by browsers before , adopt wasm Can also achieve . such as , If you put ffmpeg use WebAssembly After compiling , Then the browser will be able to play except mp4 More video formats than , This really breaks through many limitations of the browser itself
future , There will be more WebAssembly Applications appear , Some applications that can only run on the desktop , Will follow WebAssembly The development of , More appear in web Application
边栏推荐
- Duchefa low melting point agarose PPC Chinese and English instructions
- EN 438-7建筑覆盖物装饰用层压板材产品—CE认证
- 从架构上详解技术(SLB,Redis,Mysql,Kafka,Clickhouse)的各类热点问题
- How to open an account online for futures? Is it safe?
- 台风来袭!建筑工地该如何防范台风!
- Norgen AAV提取剂盒说明书(含特色)
- Binary search
- Prior knowledge of machine learning in probability theory (Part 1)
- 研學旅遊實踐教育的開展助力文旅產業發展
- 大二下个人发展小结
猜你喜欢

haas506 2.0开发教程 - 阿里云ota - pac 固件升级(仅支持2.2以上版本)

研學旅遊實踐教育的開展助力文旅產業發展

教你自己训练的pytorch模型转caffe(一)

10000+ 代码库、3000+ 研发人员大型保险集团的研发效能提升实践

王老吉药业“关爱烈日下最可爱的人”公益活动在南京启动

Duchefa cytokinin dihydrozeatin (DHZ) instructions

解析五育融合之下的steam教育模式

如何让化工企业的ERP库存账目更准确

Open source SPL eliminates tens of thousands of database intermediate tables

当Steam教育进入个性化信息技术课程
随机推荐
Abnova maxpab mouse derived polyclonal antibody solution
Interpreting the daily application functions of cooperative robots
Is it safe to open a stock account by mobile phone? My home is relatively remote. Is there a better way to open an account?
CADD course learning (7) -- Simulation of target and small molecule interaction (semi flexible docking autodock)
leetcode:1139. 最大的以 1 为边界的正方形
MySQL InnoDB架构原理
leetcode:1755. 最接近目标值的子序列和
AITM2-0002 12s或60s垂直燃烧试验
Research and development efficiency improvement practice of large insurance groups with 10000 + code base and 3000 + R & D personnel
Popular science | does poor English affect the NPDP exam?
ts 之 泛型
教你自己训练的pytorch模型转caffe(三)
Abbkine trakine F-actin Staining Kit (green fluorescence) scheme
systemd-resolved 开启 debug 日志
Abnova CRISPR spcas9 polyclonal antibody protocol
Duchefa d5124 md5a medium Chinese and English instructions
台风来袭!建筑工地该如何防范台风!
解读协作型机器人的日常应用功能
POJ 3414 pots (bfs+ clues)
AITM 2-0003 水平燃烧试验