JS 实现CSV文件转换SQL文件小工具

一. 需求

最近在项目中遇到一个问题,客户提供的数据是CSV格式的,
需要将CSV文件中的数据转换为SQL语句文件。

😅由于本人不会Excel的vba编程,因此决定使用JS来实现。


二. 实现思路

  • 提供一个文件上传框,支持多文件上传,且只能上传csv文件
  • 使用new FileReader()来读取上传的csv文件
  • 每个csv文件都包含标题栏,因此需要从第二行开始读取数据
  • 将读取到的数据构造成insert的sql语句然后存放到一个list中
  • 创建Blob对象,将包含sql的list放入该对象中构建sql文本对象
  • 通过URL.createObjectURL()获取Blob对象在内存中的地址
  • 创建a标签,配合内存中的地址实现sql文件下载

三. CSV文件例子

"CQ企画番号","共同購入商品コード","CQ商品コード","JANコード","定催区分","部門コード","大分類","中分類","小分類","集品区分","商品名漢字","規格名漢字","入数","納品時容器区分","シール貼付有無区分","資材名","税抜組合員単価","税込組合員単価","企画年月回","配達年月回","企画単協 エフ","企画単協 さが","企画単協 ララ","企画単協 おおいた","企画単協 水光社","企画単協 みやざき","企画単協 かごしま","企画単協 おきなわ","税コード","消費税率","単価計算区分","税抜計算区分","税込計算区分","禁則チェック区分","エラーコード","削除フラグ","作成日","作成時刻","更新日","更新時刻"
"301","1005405","100317290","2000000432908","1","02","01","02","09","02","フレンドリーバナナ(フィリピン産)","750g",1,"2","0",,288,311,"2023041","       ","0","0","0","0","0","0","0","1","080",0.08,"2","2","1","1","  ","0","20230117","100742","20230309","102624"
"301","1039130","100499798","2000000648941","1","02","01","02","09","02","フレンドリーバナナ(フィリピン産)","500g(3?5本)",1,"2","0",,278,300,"2023041","       ","0","0","0","0","0","0","0","1","080",0.08,"2","2","1","1","  ","0","20230117","100742","20230309","102624"
"301","1355180","800022912","2008000229122","1","01","01","01","02","02","貝割大根(大分県産)","1パック",20,"2","0",,36,38,"2023041","       ","0","0","0","1","0","0","0","0","080",0.08,"2","2","1","1","  ","0","20230117","100742","20230309","102624"
"301","1395165","800055699","2000000678788","1","01","01","00","05","02","たまねぎ(北海道産)","300g(大小混)",1,,"0",,138,149,"2023041","       ","0","0","0","0","0","0","0","1","080",0.08,"2","2","1","1","  ","0","20230117","100742","20230309","102624"
"301","1409182","100433518","2000000601557","2","01","01","00","05","00","よくねたいも〈北あかり〉(北海道産)","500g(大小混)",1,"1","0",,258,278,"2023041","       ","0","0","0","0","0","0","0","1","080",0.08,"2","2","1","1","  ","0","20230302","130441","20230309","102458"
"301","1417550","800072337","2008000723378","1","01","01","00","01","05","ほうれん草(長崎県産)","150g",1,"2","0",,138,149,"2023041","       ","0","0","1","0","0","0","0","0","080",0.08,"2","2","1","1","  ","0","20230117","100742","20230309","102624"

四. 转换工具

  • 复制代码创建html文件,拿来就用。😋不用配置环境
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>CSV转换SQL工具</title>
</head>
<body><div style="display: flex;"><label for="schema">指定schema</label><select id="schema"><option value=""></option><option value="nosan">nosan 农业</option><option value="sozai">sozai 蔬菜</option><option value="shokan">shokan 商管</option></select></div><hr><label for="removeBlank">是否去除字符串中的空白</label><input id="removeBlank" type="checkbox" /><hr><label for="csv">请上传csv文件</label><input id="csv" type="file" accept=".csv" multiple /><hr><button id="transform">csv转sql开始</button><hr><!-- 显示错误消息的区域 --><div id="error" style="color: red;"></div>
</body>
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script>// 是否去除字符串空白flaglet removeBlank = false;$(function() {transformEvent();});function transformEvent() {$("#transform").click(function() {removeBlank = $("#removeBlank").prop("checked");const schema = $("#schema").val();if(!schema) {alert("请指定schema!");return;}// 清空所有的内容$("#error").empty();// 获取上传的所有csv文件const csvFileList = $("#csv").get(0).files;for(csvfile of csvFileList) {const sqlList = [];/*将上传的文件名称当做表名注意:下面这行代码不能放到reader的load回调里面,否则生成的csv的文件名会相同*/const tableName = csvfile.name.split(".")[0];// 创建csv文件读取对象const reader  = new FileReader();// 指定要读取的CSV的编码reader.readAsText(csvfile, "Shift_JIS");reader.addEventListener('load', ({target: {result: csvText}}) => {// 获取出标题栏之外的csv内容数据const hanleCSVData = csvText.slice(csvText.indexOf('\n') + 1).split('\n');// 如果上传的csv文件只有标题没有数据if(!hanleCSVData || hanleCSVData.length === 1 && !hanleCSVData[0].trim()) {const newHtml = $("#error").html() + "<br />" + tableName + ".csv文件没有内容!";$("#error").html(newHtml);return;}for (const csvRowData of hanleCSVData) {if (!csvRowData) {continue;}// 构造插入SQLlet insertSql = SqlUtils.createBaseSql(schema, tableName);// 创建要插入sql的值const sqlValueStr = SqlUtils.addCsvRowToSqlItem(csvRowData);// 补足自定义项目后,构建const insertSqlStr = SqlUtils.customeSqlHandle(insertSql + sqlValueStr);sqlList.push(insertSqlStr);}// 下载转换之后的sql文件fileDownload(sqlList, `${tableName}.sql`);});}});};class SqlUtils {// 获取当前时间 yyyy/MM/dd HH:mm:ssstatic nowDate = new Date().toLocaleString();// 是否去除字符串中的空白static trimStrFlg = true;// 创建基本的插入SQL语句static createBaseSql(schema, tableName) {// 因为csv项目和表项目完全一致,因此可以省略项目return `INSERT INTO [${schema}].${tableName} VALUES (`;}static addCsvRowToSqlItem(csvRowData) {let sqlItem = "";// 获取CSV所有的列const csvItemList = csvRowData.split(",");const newcsvItemList = [];// 对csv项目进行特殊处理for (const csvItem of csvItemList) {if(!!csvItem) {/*如果需要去除空格,并且是csv中的字符串项目的话*/if (removeBlank && csvItem.includes("\"")) {// "测试     "   ===> '测试'newcsvItemList.push("\'" + csvItem.replaceAll('"', '').trim() + "\'");} else {// 插入的是数字newcsvItemList.push(csvItem);}} else {// 如果csv项目为空项目则插入NULLnewcsvItemList.push('NULL');}}// 将list转换为以 , 分隔的字符串,并把 " 替换为 ' ,因为sql插入时只能用 'return newcsvItemList.join(", ").replaceAll('\"', '\'') + ", ";}static customeSqlHandle(insertSql) {// 插入时间const SKSI_NCHJ = `'${SqlUtils.nowDate}'`;// 更新时间const KUSHN_NCHJ = `'${SqlUtils.nowDate}'`;// 添加换行符return `${insertSql}${SKSI_NCHJ}, ${KUSHN_NCHJ});\r\n`;}}function fileDownload(data, fileName) {// 创建文件下载的urlconst insertSqlStrBlob = new Blob(data, {type: "application/sql"});const src = URL.createObjectURL(insertSqlStrBlob);// 创建a标签const aElement = document.createElement('a');aElement.download = fileName;aElement.style.display = 'none';aElement.href = src;// 将a标签添加到页面上手动触发点击事件,从而触发文件下载document.body.appendChild(aElement);aElement.click();document.body.removeChild(aElement);URL.revokeObjectURL(src);}
</script>
</html>

五. 效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/13295.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

并发编程_jmm部分

1. JMM 理解 前提&#xff1a;并发编程有3大问题&#xff0c;可见性、有序性、原子性。 导致可见性的原因是缓存&#xff0c;有序性的原因是 编译器优化。解决方法就是直接禁用缓存和编译器优化&#xff0c;导致程序性能堪忧。 因此合理的方案就是按需禁用缓存和编译器优化。 …

ATFX国际:大非农数据来袭,美国劳动力市场需求或空前旺盛

ATFX国际&#xff1a;昨日晚间公布的ADP数据震惊市场&#xff0c;新增就业人口高达49.7万人&#xff0c;而预期值仅为22.8万人&#xff0c;前值也只有26.7万人。公布值约为预期值和前值的总和。 ▲ATFX图 ADP数据是非农就业报告的前瞻指标&#xff0c;前者表现亮眼&#xff0c…

【算法集训之线性表篇】Day 01

文章目录 题目知识点补充思路分析代码实现运行结果 题目 01.从顺序表中删除具有最小值元素&#xff08;假设唯一&#xff09;并返回被删元素的值。空出位置由最后一个元素填补&#xff0c;若顺序表为空&#xff0c;则显示出错信息并退出运行。 知识点补充 顺序表的特点是逻辑…

Handshake failed due to invalid Upgrade header: null 解决方案以及连接60s,信息不交互,连接断开

Handshake failed due to invalid Upgrade header: null 解决方案以及连接60s&#xff0c;信息不交互&#xff0c;连接断开 1. 问题背景&#xff1a;因为后端用了nginx代理&#xff0c;所以websocket连接的过程中报错&#xff1a;Handshake failed due to invalid Upgrade hea…

Elasticsearch:跨集群复制应用场景及实操 - Cross Cluster Replication

通过跨集群复制&#xff08;Cross Cluster Replication - CCR&#xff09;&#xff0c;你可以跨集群将索引复制并实现&#xff1a; 在数据中心中断时继续处理搜索请求防止搜索量影响索引吞吐量通过在距用户较近的地理位置处理搜索请求来减少搜索延迟 跨集群复制采用主动 - 被…

HTML5+CSS3+JS小实例:背景动态变化的登录界面2.0

实例:背景动态变化的登录界面2.0 技术栈:HTML+CSS+JS 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" con…

Chapter 4: Functions | Python for Everybody 讲义笔记_En

文章目录 Python for Everybody课程简介FunctionsFunction callsBuilt-in functionsType conversion functionsMath functionsRandom numbersAdding new functionsDefinitions and usesFlow of executionParameters and argumentsFruitful functions and void functionsWhy fun…

【广州华锐互动】VR地铁安全应急疏散模拟演练系统

VR地铁安全应急疏散模拟演练系统是一种利用虚拟现实技术模拟铁路安全事故的应用程序。该系统具有以下功能和内容&#xff1a; 多种场景和情境&#xff1a;用户可以选择不同的场景和情境进行模拟&#xff0c;例如列车脱轨、火灾、爆炸等。 操作控制器或手势识别技术&#xff1…

TypeScript 中【类型断言】得使用方法

类型断言的概念 有些时候开发者比TS本身更清楚当前的类型是什么&#xff0c;可以使用断言&#xff08;as&#xff09;让类型更加精确和具体。 类型断言&#xff08;Type Assertion&#xff09;表示可以用来手动指定一个值的类型。 类型断言语法&#xff1a; 值 as 类型 或 <…

2.3 Web应用 -- 2. HTTP 连接

2.3 Web应用 -- 2. HTTP 连接 HTTP连接的两种类型非持久性连接响应时间分析与建模持久性HTTP HTTP连接的两种类型 非持久性连接(Nonpersistent HTTP) 每个TCP连接最多允许传输一个对象HTTP 1.0版本使用非持久性连接 持久性连接(Persistent HTTP) 每个TCP连接允许传输多个对象H…

Dubbo hystrix 熔断降级 详细示例 多服务 公共api

目录 介绍 demo-api pom 目录 代码api provider 服务提供者 目录 pom 服务实现代码 启动代码 配置 日志 consumer 消费者 目录 pom 调用service接口 调用serviceImpl类 ctr 配置 页面调用熔断效果 相关文章 介绍 因为网上和官网拷贝的文档发现有很多版本…

PyQt如何查找帮助信息(不会写组件的代码,快看过来!)

1.可以在PyQt6官网中查找信息kReference Guide — PyQt Documentation v6.5.1 看不懂没有关系啦&#xff0c;可以使用网页翻译哒~ 找到或者直接搜索QLabel&#xff0c;寻找对应函数即可 2. https://zetcode.com/pyqt6/ 3.Qt Creator中寻找 例如&#xff0c;输入setText 就可以…