office EXCEL文档有合并表格功能,WPS基础功能免费,但合并表格要充SSSSSS VIP
我又没有office EXCEL,我又不想充 WPS VIP,所以我研究了这个用js合并的方法。
如果你对js和excel有兴趣,你也可以好好研究 js-xlsx,用代码去处理excel。代码的灵活性要比WPS强多了。
界面如图左侧所示。(右侧绿框是按F12弹出的调试界面,可显示调试信息)
按顺序操作1,2,3,4,5,即可拼接第1个表和第2个表。
(上图)左下角可生成示例用于拼接的表1和表2
图2-示例表
- 拼接表的必要条件是:有相同的属性(列名/字段)-且该属性值是唯一的,如学号220101,不管你一条数据还是一百万条数据,这个学号都不能重复。但姓名可以重复,所以姓名不应用来做拼接数据的ID。
- 表2需要被拼接的字段,如这里的语文、数学,需要拼接哪个就填到第二个输入框里。但是因为表1已经有学号、姓名,所以这里不需要重复填写学号姓名。‘’随机排序‘’字段是我用随机数生成的,用于打乱排序,验证能否找到相同学号对应行数据。你可以忽略这个字段。
- 注意,表1是全体学生表,表2是部分学生成绩。表2的学号一定存在于表1。
拼接效果:
图3-拼接结果表点此去github下载代码
下载说明THE END.
如果能正常下载zip,下面内容可以不用看了。下载文件夹找到直接双击join.htm即可使用。
DIY----想要得到图1的“网页”,需要:
1、新建文件夹(任意名字,任意目录),例如叫‘js处理excel’,放桌面
图4-文档文件夹
2、其中,join.htm是我参照别人写的‘网页’,xlsxtool.js是工具文件(实际这里文件都是txt文档-纯文本,然后修改后缀,.txt改为.htm,.js。)
后面会给出join.htm,xlsxtool.js的代码。
【js】这个目录/文件夹,就必须起'js'这个名字(否则你就要改代码里的引用路径)并放在'js处理excel'目录下。
【js】里面是三个js文件,其中1,2是网上下载的官方工具插件,3是我抄写的工具。
图6-目录2
xlsx.core.min.js下载
JQuery各版本下载
xlsx.xxxxx.js直接就能下载。
jquery各个版本都能用,但如果下载其他版本,需要把名称改为'jquery-3.0.0.min.js',或者在代码里修改引用名。这个文件好像不能直接下载,你可以复制如下图红字‘’处的路径,粘贴到浏览器地址栏后,即可得到插件代码。然后'Alt+A'全选,复制代码,粘贴到一个空的txt文本。修改文本名称(包括txt后缀)为'jquery-3.0.0.min.js'保存即可。
至于官网各个版本,uncompressed,minified,slim,slim minified,实际就是全功能版本、简化功能版本的区别。我们只要简化版本就可以了,否则文件体积会较大。
图7-JQuery下载
最后,是我们自己的代码:
不要看到‘代码’就害怕,无非都是一些txt纯文本,只不过有固定格式而已,然后把后缀'xxx.txt'改成'xxx.htm','xxx.js'而已
join.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<!-- 网络加载 jquery -->
<!-- <script src="https://code.jquery.com/jquery-3.0.0.min.js" integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script> -->
<!-- 本地jquery -->
<script src="js/jquery-3.0.0.min.js"></script>
<script src="js/xlsx.core.min.js"></script>
<script src="js/xlsxtool.js"></script>
</head>
<body>
<p id="p1">第1个表</p>
<input type="file" id="excel-file1" name="">
<p id="p2">第2个表</p>
<input type="file" id="excel-file2" name="">
<p><a style="color:blue;">ID</a>(匹配字段-2个表中相同的列名称,如2个表的学生学号一致且值唯一,就填"<a style="color:red;">学号</a>")</p>
<p style="font-size: smaller">表1第1行和表2哪一行拼接呢?那肯定是张三的成绩拼到张三那一行啊!但学校可能有2个张三,但学号是唯一的,所以用学号做ID(数据匹配依据)</p>
<input type="text" id="tbID" placeholder="2个表相同且值唯一的列名">
<p><a style="color:blue;">拼接字段</a>(第2个表参与拼接的列,如要把第2个表的数学、语文列拼接到新表,则填"<a style="color:red;">数学,语文</a>",中间逗号隔开)</p>
<input type="text" id="appends" placeholder="新增列名1,列名2,..">
<p>拼接2个表</p>
<button type="button" onclick="clickJoin(this)">拼接2个成表</button>
<p class="tips">测试数据-示例</p>
<button class="btn-gen1" type="button" onclick="clickGenTable1(this)">下载学生表</button>
<button class="btn-gen2" type="button" onclick="clickGenTable2(this)">下载学生成绩表</button>
</body>
<script>
$('#excel-file1').change(function (e) {
document.getElementById('p1').innerHTML = '第1个表(已获取)'
var files = e.target.files;
var fileReader = new FileReader();
fileReader.onload = function (ev) {
try {
var data = ev.target.result,
workbook = XLSX.read(data, {
type: 'binary'
}), // 以二进制流方式读取得到整份excel表格对象
persons = []; // 存储获取到的数据
} catch (e) {
console.log('文件类型不正确');
return;
}
// 表格的表格范围,可用于判断表头是否数量是否正确
var fromTo = '';
// 遍历每张表读取
// !!!workbook.Sheets是一个对象!!不是数组!
console.log('=====workbook1=====:')
console.log(workbook)
for (var propertyName in workbook.Sheets) {
console.log('propertyName: ' + propertyName)
if (workbook.Sheets.hasOwnProperty(propertyName)) {
var sheet = workbook.Sheets[propertyName]
// console.log(sheet)
fromTo = sheet['!ref'];
console.log('fromTo: ' + fromTo);
firstTableRows = XLSX.utils.sheet_to_json(sheet)
persons = persons.concat(firstTableRows);
break; // 如果只取第一张表,就取消注释这行
}
}
console.log('表-json对象1:');
console.log(firstTableRows);
// let jsonString = JSON.stringify(firstTableRows)
// console.log(jsonString);
};
// 以二进制方式打开文件
fileReader.readAsBinaryString(files[0]);
});
$('#excel-file2').change(function (e) {
document.getElementById('p2').innerHTML = '第2个表(已获取)'
var files = e.target.files;
var fileReader = new FileReader();
fileReader.onload = function (ev) {
try {
var data = ev.target.result,
workbook = XLSX.read(data, {
type: 'binary'
}), // 以二进制流方式读取得到整份excel表格对象
persons = []; // 存储获取到的数据
} catch (e) {
console.log('文件类型不正确');
return;
}
// 表格的表格范围,可用于判断表头是否数量是否正确
var fromTo = '';
// 遍历每张表读取
// !!!workbook.Sheets是一个对象!!不是数组!
console.log('=====workbook2=====:')
console.log(workbook)
for (var propertyName in workbook.Sheets) {
console.log('propertyName: ' + propertyName)
if (workbook.Sheets.hasOwnProperty(propertyName)) {
var sheet = workbook.Sheets[propertyName]
// console.log(sheet)
fromTo = sheet['!ref'];
console.log('fromTo: ' + fromTo);
secondTableRows = XLSX.utils.sheet_to_json(sheet)
persons = persons.concat(secondTableRows);
break; // 如果只取第一张表,就取消注释这行
}
}
console.log('表-json对象2:');
console.log(secondTableRows);
};
// 以二进制方式打开文件
fileReader.readAsBinaryString(files[0]);
});
function clickJoin(argument) {
// body...
console.log('点击了‘拼接’按钮')
// jsonToExcel( sheet1data, 'demo.xls');
// testGen()
if(!firstTableRows) {
alert('请先选择第1个表')
}else if(!secondTableRows) {
alert('请先选择第2个表')
}else {
let idStr = document.getElementById('tbID').value
console.log(idStr)
let appends = document.getElementById('appends').value
console.log(appends)
if (!idStr) {
alert('请先填写ID')
return
}
if(!appends) {
alert('请先填写拼接字段')
return
}
let appendsArr = []
if(appends.indexOf(',') != -1) {
appendsArr = appends.split(',')
}else if(appends.indexOf(',') != -1) {
appendsArr = appends.split(',')
}else if(appends.indexOf(';') != -1) {
appendsArr = appends.split(';')
}else if(appends.indexOf(';') != -1) {
appendsArr = appends.split(';')
}
console.log(appendsArr)
for (var i = 0; i < firstTableRows.length; i++) {
let t1row = firstTableRows[i]
for (var j = 0; j < secondTableRows.length; j++) {
let t2row = secondTableRows[j]
// if(t2row['学号'] == t1row['学号']) {
// t1row['语文'] = t2row['语文']
// t1row['数学'] = t2row['数学']
// }
if (t2row[idStr] == t1row[idStr]) {
for (var k = 0; k < appendsArr.length; k++) {
let key = appendsArr[k]
// console.log('key = ' + key)
if (t2row[key] !== undefined) {
t1row[key] = t2row[key]
}
}
}
}
}
xtGenExcel(firstTableRows, '拼接表')
}
}
function clickGenTable1(argument) {
// body...
testGenStudents()
}
function clickGenTable2(argument) {
// body...
testGenResults()
}
// demo调用演示
let sheet1data = [ // 注意数组中每列key的排序,因为导出列表时按照key的排序导出的
{ 部门: '行政部', 姓名: 'zhangsan', age: 18 },
{ 部门: 'IT', 姓名: 'lisi', age: 19 },
];
var firstTableRows = undefined
var secondTableRows = undefined
</script>
<style type="text/css">
.tips {
position: fixed;
bottom: 30px;
left: 20px;
color: #333333;
font-size: small;
}
.btn-gen1 {
position: fixed;
bottom: 10px;
left: 20px;
color: blue;
}
.btn-gen2 {
position: fixed;
bottom: 10px;
left: 120px;
color: blue;
}
</style>
</html>
xlsxtool.js
// 导入文件
document.write("<script language = javascript src = 'js/xlsx.core.min.js'></script>")
function testGen() {
// body...
xtGenExcel(testData)
}
function testGenStudents() {
// body...
xtGenExcel(students, '学生表')
}
function testGenResults() {
// body...
xtGenExcel(examResults, '学生成绩表')
}
function xtGenExcel(rows, bookName = 'MYBOOK', sheetName = 'sheet1') {
// body...
const workbook = XLSX.utils.book_new();
const worksheet = XLSX.utils.json_to_sheet(rows);
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
// 给 sheet 添加【表头】
// XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
// 调整适应列宽
// const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
// 第一列列宽 = max_width, 第二列列宽 = 10。 wch:
// worksheet["!cols"] = [ { wch: max_width } , {wch: 10}];
// 输出 excel
XLSX.writeFile(workbook, bookName + ".xlsx", { compression: true });
}
// 这个方法不需要 xlsx 插件。
function jsonToExcel(jsonData, filename = 'export.xls') {
if (!Array.isArray(jsonData) || !jsonData?.length) {
return;
}
let str = '';
// 列标题
Object.keys(jsonData[0]).forEach(k => {
str += k + '\t,';
});
str += '\n';
// 增加\t为了不让表格显示科学计数法或者其他格式
for (let i = 0; i < jsonData.length; i++) {
// eslint-disable-next-line no-loop-func
Object.keys(jsonData[i]).forEach(key => {
str += `${jsonData[i][key] + '\t'},`;
});
str += '\n';
}
console.log(str)
// str = '1,2,3,4,\n11,22,33,44,55,66,\na,b,c,d,\nhello' // \n 换行,也是excel换行。逗号则是代表一列
// encodeURIComponent解决中文乱码
const uri = `data:text/${filename.split('.').pop()};charset=utf-8,\ufeff${encodeURIComponent(str)}`;
console.log(uri)
// 通过创建a标签实现
let dom = document.createElement('a');
dom.download = filename;
dom.style.display = 'none';
dom.href = uri;
document.body.appendChild(dom);
dom.click();
setTimeout(() => {
document.body.removeChild(dom);
}, 1000);
}
const students = [{"学号":220101,"姓名":"细狗你","班级":1,"性别":"男","年龄":12},{"学号":220102,"姓名":"细鬼","班级":1,"性别":"男","年龄":11},{"学号":220103,"姓名":"渣渣辉","班级":1,"性别":"男","年龄":14},{"学号":220201,"姓名":"吴君如","班级":2,"性别":"女","年龄":12},{"学号":220202,"姓名":"苑琼丹","班级":2,"性别":"女","年龄":13},{"学号":220301,"姓名":"张三","班级":3,"性别":"男","年龄":13},{"学号":220302,"姓名":"王麻子","班级":3,"性别":"女","年龄":12},{"学号":220303,"姓名":"二狗子","班级":3,"性别":"男","年龄":12},{"学号":220304,"姓名":"李四","班级":3,"性别":"男","年龄":13},{"学号":220305,"姓名":"陈华春","班级":3,"性别":"女","年龄":14},{"学号":220306,"姓名":"赵丽华","班级":3,"性别":"女","年龄":12},{"学号":220401,"姓名":"坤哥","班级":4,"性别":"男","年龄":12},{"学号":220402,"姓名":"梁坤","班级":4,"性别":"男","年龄":12},{"学号":220403,"姓名":"梁晨","班级":4,"性别":"男","年龄":12},{"学号":220404,"姓名":"梅静","班级":4,"性别":"女","年龄":12},{"学号":220405,"姓名":"韩汉晨","班级":4,"性别":"男","年龄":13},{"学号":220406,"姓名":"凌楚峰","班级":4,"性别":"男","年龄":12}]
const examResults = [{"学号":220303,"姓名":"二狗子","语文":62,"数学":88,"随机排序":0.534449607369229},{"学号":220301,"姓名":"张三","语文":64,"数学":98,"随机排序":0.166291769352402},{"学号":220101,"姓名":"细狗你","语文":99,"数学":96,"随机排序":0.298748966878335},{"学号":220305,"姓名":"陈华春","语文":83,"数学":94,"随机排序":0.981885816605045},{"学号":220306,"姓名":"赵丽华","语文":87,"数学":97,"随机排序":0.777319924734964},{"学号":220405,"姓名":"韩汉晨","语文":63,"数学":100,"随机排序":0.0758610844747052},{"学号":220403,"姓名":"梁晨","语文":69,"数学":76,"随机排序":0.160749347477528},{"学号":220402,"姓名":"梁坤","语文":52,"数学":83,"随机排序":0.329833118669286},{"学号":220404,"姓名":"梅静","语文":43,"数学":100,"随机排序":0.844087333621201},{"学号":220302,"姓名":"王麻子","语文":67,"数学":66,"随机排序":0.376213770771804},{"学号":220401,"姓名":"坤哥","语文":100,"数学":97,"随机排序":0.736891795092198},{"学号":220304,"姓名":"李四","语文":47,"数学":59,"随机排序":0.801160817943515},{"学号":220406,"姓名":"凌楚峰","语文":55,"数学":98,"随机排序":0.0735291866946264}]
const testData = [
{ name: "George Washington", birthday: "1732-02-22" },
{ name: "John Adams", birthday: "1735-10-19" },
]
网友评论