nodejs操作excel文件实例,读取sheets, 设置cell颜色
本代码是我帮客户做的兼职的实例,涉及用node读取excel文件,遍历sheets,给单元格设置颜色等操作,希望对大家接活有所帮助。
gen.js
let dir="Z:\\武汉烟厂\\山东区域\\备档资料\\销区零售终端APP维护清单\\走访档案\\2024年6月\\200户走访档案\\修改\\";
let dir2="Z:\\liujuan\\new_gen4\\";const fs = require('fs');
const path = require('path');
const ExcelJS = require('exceljs');// get text in cell
function gv(cell) {let v=cell.value; if(!v) return '';v = (v.richText? v.richText.map(({ text }) => text).join(''): v.toString());return v.trim().toLowerCase().replace(/[(]/g, '(').replace(/[)]/g, ')').replace(/\s/g, '');
}async function make_console(filename, sheetname, list)
{const FilePath = path.join(dir2, `console_${filename}_${sheetname}.js`); const file_content=`
let sheet_name="${sheetname}";
let list=${list};
let diffs='', diffj=[]; let nl='\\r\\n';
let noinput=document.getElementById('licensenum');
function check_one(list, itemno)
{ if(itemno>=list.length){ console.log(diffs); console.log(diffj); return; }console.log('checking '+itemno);let item=list[itemno]; let { no }=item; noinput.value=no; queryInfo(); setTimeout(()=>{let diff={no, cols:[]}; let pushed_diff=false;let tbody=document.getElementById('detailTbodyId'); if(!tbody || !tbody.children || tbody.children.length<1 || !tbody.children[0].children || tbody.children[0].children.length<4){ let msg='许可证不存在1: '+no; console.log(msg); diffs+=(msg+nl+nl); diffj.push(diff); check_one(list, itemno+1); return; }let tds=tbody.children[0].children; if(tds[0].innerText.toLowerCase().trim()!=no) { let msg='许可证不存在2: '+no; console.log(msg); diffs+=(msg+nl+nl); diffj.push(diff); check_one(list, itemno+1); return; }if(tds[1].innerText.toLowerCase().trim().replace(/[(]/g, '(').replace(/[)]/g, ')').replace(/\\s/g, '')!=item.company) { if(!pushed_diff) { pushed_diff=true; diffj.push(diff); } diff.cols.push('company'); diffs+=(no+': '+nl+tds[1].innerText+nl+item.company+nl+nl);}if(tds[2].innerText.toLowerCase().trim().replace(/[(]/g, '(').replace(/[)]/g, ')').replace(/\\s/g, '')!=item.addr) { if(!pushed_diff) { pushed_diff=true; diffj.push(diff); } diff.cols.push('addr'); diffs+=(no+': '+nl+tds[2].innerText+nl+item.addr+nl+nl);}if(!tds[3].innerText.toLowerCase().includes(item.date)) { if(!pushed_diff) { pushed_diff=true; diffj.push(diff); } diff.cols.push('date'); diffs+=(no+': '+nl+tds[3].innerText+nl+item.date+nl+nl);}check_one(list, itemno+1);}, 2000);
}
check_one(list, 0);
`;fs.writeFileSync(FilePath, file_content);
}async function make_mark(filename, sheetname)
{const FilePath = path.join(dir2, `mark_${filename}_${sheetname}.js`); const file_content=`
let diffs=
;
let filename='${filename}';
let sheet_name="${sheetname}";
let dir="${ dir.replace(/\\/g, "\\\\") }";
const ExcelJS = require('exceljs');
const fs = require('fs');let style_red={font:{color:{ argb: 'FFFF0000'}}};
let style_black={font:{color:{ argb: 'FF000000'}}};
let style_blue={font:{color:{ argb: 'FF0000FF'}}};
function gv(cell) {let v=cell.value; if(!v) return '';v = (v.richText? v.richText.map(({ text }) => text).join(''): v.toString());return v.trim().toLowerCase().replace(/[(]/g, '(').replace(/[)]/g, ')').replace(/\\s/g, '');
}async function ProcessSheet(sheet)
{let rows=sheet.rowCount, cols=sheet.columnCount;let found_first_row=false, no_col=0, addr_col=0, date_col=0, company_col=0, result=[];for(let row=1; row<=rows; row++){console.log('row: ', row);let r=sheet.getRow(row);if(found_first_row){let no_cell=r.getCell(no_col), no=gv(no_cell); if(!no){ for(let col=1; col<=cols; col++) r.getCell(col).style=style_black; continue; }let diff; if(diff=diffs.find(d=>d.no==no)){ let dcols=diff.cols;if(dcols.length==0) { for(let col=1; col<=cols; col++) r.getCell(col).style=style_black; no_cell.style=style_blue; continue;}for(let col=1; col<=cols; col++){let cell=r.getCell(col); if((company_col==col && dcols.includes('company'))||(addr_col==col && dcols.includes('addr'))||(date_col==col && dcols.includes('date'))) { cell.style=style_red; }else cell.style=style_black;} }else{ for(let col=1; col<=cols; col++) r.getCell(col).style=style_black;}}else{if(gv(r.getCell(1))=='区域' && gv(r.getCell(3))=='人员'){ // console.log('成功找到区域和人员列');for(let col=3; col<=cols; col++){let cell=r.getCell(col); let v=gv(cell);if(v=='专卖许可证名称') company_col=col; else if(v=='地址') addr_col=col; else if(v=='许可证到期日期') date_col=col; else if(v=='编号') no_col=col;}if(company_col==0 || addr_col==0 || date_col==0 || no_col==0) { console.log('未找到指定的4列'); return; }else { found_first_row=true; console.log('成功找到指定的4列'); }}}}
}async function ProcessFile(ExcelFilePath)
{const workbook = new ExcelJS.Workbook(); await workbook.xlsx.readFile(ExcelFilePath);let sheets=workbook.worksheets, sheetsCount=sheets.length;for(let sheet_index=0; sheet_index<sheetsCount; sheet_index++){let sheet=sheets[sheet_index]; if(sheet.name==sheet_name) { await ProcessSheet(sheet); break; }}await workbook.xlsx.writeFile(ExcelFilePath);
}
ProcessFile(dir+filename+'.xlsx');
`;fs.writeFileSync(FilePath, file_content);
}async function traverseFolder(folderPath) {const items = fs.readdirSync(folderPath);for(let item of items){console.log(item);if(item.toLowerCase().includes(".xlsx") && item.indexOf("~")<0){const filename=item.substring(0, item.length-5); const ExcelFilePath = path.join(folderPath, item); const workbook = new ExcelJS.Workbook(); await workbook.xlsx.readFile(ExcelFilePath);let sheets=workbook.worksheets, sheetsCount=sheets.length;for(let sheet_index=0; sheet_index<sheetsCount; sheet_index++){let sheet=sheets[sheet_index]; console.log(`sheet ${sheet.id}: ${sheet.name}`); //await ProcessSheet(sheet);let rows=sheet.rowCount, cols=sheet.columnCount; console.log(`${rows} rows, ${cols} cols`);let found_first_row=false, no_col=0, addr_col=0, date_col=0, company_col=0, result=[];for(let row=1; row<=rows; row++){let r=sheet.getRow(row);if(found_first_row){let no=gv(r.getCell(no_col)); if(!no) continue;result.push({no, addr: gv(r.getCell(addr_col)), company: gv(r.getCell(company_col)), date: gv(r.getCell(date_col)), });}else{if(gv(r.getCell(1))=='区域' && gv(r.getCell(3))=='人员'){ //console.log('成功找到区域和人员列');for(let col=3; col<=cols; col++){let cell=r.getCell(col); let v=gv(cell);if(v=='专卖许可证名称') company_col=col; else if(v=='地址') addr_col=col; else if(v=='许可证到期日期') date_col=col; else if(v=='编号') no_col=col; // console.log(` [${row}, ${col}] ${v}`);}if(company_col==0 || addr_col==0 || date_col==0 || no_col==0) { console.log('未找到指定的4列'); return; }else { found_first_row=true; console.log('成功找到指定的4列'); }}}}//console.log(result.length, result[0]);try {await make_console(filename, sheet.name, JSON.stringify(result)); await make_mark(filename, sheet.name);fs.writeFileSync(`${dir2}${filename}_${sheet.name}_差异.txt`, '');} catch (err) { console.error(err); }} }}
}traverseFolder(dir);
相关文章:
nodejs操作excel文件实例,读取sheets, 设置cell颜色
本代码是我帮客户做的兼职的实例,涉及用node读取excel文件,遍历sheets,给单元格设置颜色等操作,希望对大家接活有所帮助。 gen.js let dir"Z:\\武汉烟厂\\山东区域\\备档资料\\销区零售终端APP维护清单\\走访档案\\2024年6月…...
用GPT做足球预测案例分享
自从GPT出来后,一直想利用GPT的能力做点什么,想了很多项目,比如用GPT写小说,用GPT做股票分析,用GPT写营销文章,最终我选了一个比较有意思的方向:GPT足球预测。因为每天都有足球比赛,…...
代码随想录| 编辑距离
判断子序列[https://leetcode.cn/problems/is-subsequence/description/] 题意:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 思路:从动态规划, dp[i][j] 表示s的前i-1个元素和t的前j-1个元素相同的子序列元素的个数。 还要对d…...
MOJO编程语言的编译与执行:深入编译器与解释器的工作原理
引言 MOJO编程语言以其面向对象的特性和简洁的语法而受到开发者的欢迎。在MOJO的世界中,编译器和解释器是两个核心组件,它们负责将MOJO代码转换为机器可执行的指令。本文将探讨MOJO编译器和解释器的工作原理,以及它们如何在MOJO编程过程中发…...
nginx-限制客户端并发数
文章目录 前言一、ngx_http_limit_conn_module二、指令介绍1. limit_conn_zone2.limit_conn3. limit_conn_log_level4. limit_conn_status 案例未限制限制 总结 前言 瞬时大量用户访问服务器,导致服务器超载而宕机。 恶意请求攻击服务器,导致服务器超载…...
Vatee万腾平台:智能生活的新选择
在科技飞速发展的今天,智能生活已经不再是遥不可及的梦想,而是逐渐渗透到我们日常生活的方方面面。Vatee万腾平台,作为智能科技领域的佼佼者,正以其创新的技术、丰富的应用场景和卓越的用户体验,成为智能生活的新选择&…...
白嫖A100-interLM大模型部署试用活动,亲测有效-2.Git
申明 以下部分内容来源于活动教学文档: Docs git 安装 是一个开源的分布式版本控制系统,被广泛用于软件协同开发。程序员的必备基础工具。 常用的 Git 操作 git init 初始化一个新的 Git 仓库,在当前目录创建一个 .git 隐藏文件夹来跟踪…...
LeetCode 60.排序排列(dfs暴力)
给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。 按大小顺序列出所有排列情况,并一一标记,当 n 3 时, 所有排列如下: "123""132""213""231""312""321" 给定…...
矩阵分析与应用1-矩阵代数基础
矩阵分析与应用1-矩阵代数基础 1 矩阵的基本运算2 矩阵的初等变换3 向量空间、线性映射与Hilbert空间4 内积与范数5 随机向量6 矩阵的性能指标7 逆矩阵与伪逆矩阵8 Moore-Penrose逆矩阵9 矩阵的直和与Hadamard积10 Kronecker积与Khatri-Rao积11 向量化与矩阵化12 稀疏表示与压缩…...
Vue的学习之生命周期
一、生命周期 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Vue的学习</title><script src"vue.js" type"text/javascript" charset"utf-8"></script></head>&l…...
【MySQL】表的操作{创建/查看/修改/删除}
文章目录 1.创建表1.1comment:注释信息1.2存储引擎 2.查看表3.修改表3.1add添加列,对原数据无影响3.2drop删除列3.3modify修改列类型3.4change修改列名3.5rename [to]修改表名 4.删除表5.总结 1.创建表 CREATE TABLE table_name (field1 datatype,field…...
基于Python爬虫的城市二手房数据分析可视化
基于Python爬虫的城市二手房数据分析可视化 一、前言二、数据采集(爬虫,附完整代码)三、数据可视化(附完整代码)3.1 房源面积-总价散点图3.2 各行政区均价3.3 均价最高的10个小区3.4 均价最高的10个地段3.5 户型分布3.6 词云图四、如何更换城市一、前言 二手房具有价格普…...
这款新的 AI 语音助手击败了 OpenAI,成为 ChatGPT 最受期待的功能之一
OpenAI 推迟了 ChatGPT 令人印象深刻的语音模式,这让许多 AI 聊天机器人的粉丝感到不安,但他们现在可能已经被挖走了。法国人工智能开发商 Kyutai 推出了一款名为 Moshi 的实时语音 AI 助手。 Moshi 旨在通过语音(如 Alexa 或 Google Assista…...
CTS单测某个模块和测试项
1 ,测试单个模块命令 run cts -m <模块名> 比如:run cts -m CtsUsbTests模块名可以从测试报告中看,如下: 2, 测试单个测试项 run cts -m <模块名> -t <test_name> 比如:run cts -m ru…...
pytorch、pytorch_lightning、torchmetrics版本对应
目录 1.pytorch_lightning对应版本安装 2.PyTorch Lightning介绍 PyTorch Lightning 的作用: PyTorch Lightning 的基本用法: 报错:ModuleNotFoundError: No module named pytorch_lightning 这种报错一看就是缺了pytorch_lightning包&am…...
麒麟系统部署JeecgBoot
一、安装jdk 自带的即可,不必另外安装 二、安装MySQL 麒麟系统安装MySQL_麒麟系统安装万里数据库步骤-CSDN博客 三、安装Redis 麒麟系统安装Redis_麒麟上redis-CSDN博客 四、安装Nginx 1、下载 下载地址:https://redis.io/ 2、解压配置 tar .…...
要想贵人相助,首先自己得先成为贵人!
点击上方△腾阳 关注 转载请联系授权 在金庸江湖里,有两位大侠,一个是萧峰,一个是郭靖。 郭靖在《射雕英雄传》里是绝对的主角,在《神雕侠侣》当中也是重要的配角,甚至可以说是第二主角。 谈起郭靖,很多…...
使用块的网络 VGG
一、AlexNet与VGG 1、深度学习追求更深更大,使用VGG将卷积层组合为块 2、VGG块:3*3卷积(pad1,n层,m通道)、2*2最大池化层 二、VGG架构 1、多个VGG块后接全连接层 2、不同次数的重复块得到不同的架构&a…...
微信小程序性能与体验优化
1. 合理的设置可点击元素的响应区域大小; 比较常见的是页面的点击按钮太小,用户点击不到按钮,这样用户体验很不好。 2. 避免渲染页面耗时过长; 当页面渲染时间过长的话,会让用户感觉非常卡顿,当出现这种…...
Android14之获取包名/类名/服务名(二百二十三)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
