|
@@ -0,0 +1,241 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="zh-cn">
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <title>课表导入导出</title>
|
|
|
+ <meta name="description" content="使用sheetjs读取和导出excel">
|
|
|
+ <style type="text/css">
|
|
|
+ table {
|
|
|
+ border-collapse: collapse;
|
|
|
+ }
|
|
|
+ th, td {
|
|
|
+ border: solid 1px #6D6D6D;
|
|
|
+ padding: 5px 10px;
|
|
|
+ }
|
|
|
+ .mt-sm {margin-top: 8px;}
|
|
|
+ body {
|
|
|
+ background: #f4f4f4;
|
|
|
+ padding: 0;
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+ .container {
|
|
|
+ width: 1024px;
|
|
|
+ margin: 0 auto;
|
|
|
+ background: #fff;
|
|
|
+ padding: 20px;
|
|
|
+ min-height: 100vh;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <div class="container">
|
|
|
+ <h2>读取excel</h2>
|
|
|
+ <div class="mt-sm">
|
|
|
+ <input type="file" id="file" style="display:none;" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"/>
|
|
|
+ <a href="javascript:selectFile()">加载本地excel文件</a>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <p>结果输出:(下面表格可直接编辑导出)</p>
|
|
|
+ <div id="result" contenteditable></div>
|
|
|
+
|
|
|
+ <h2>导出excel</h2>
|
|
|
+ <div class="mt-sm" style="padding-bottom:40px;">
|
|
|
+ <input type="button" onclick="exportExcel()" value="保存"/> 上面读取的表格您可以直接编辑,编辑后点击保存即可导出excel文件。
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <h2>导出带单元格合并的excel</h2>
|
|
|
+ <input type="button" value="导出" onclick="exportSpecialExcel()"/>
|
|
|
+ </div>
|
|
|
+ <script type="text/javascript" src="./js/jquery.min.js"></script>
|
|
|
+ <script type="text/javascript" src="./js/xlsx.core.min.js"></script>
|
|
|
+ <script type="text/javascript">
|
|
|
+
|
|
|
+ function selectFile() {
|
|
|
+ document.getElementById('file').click();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 读取本地excel文件
|
|
|
+ function readWorkbookFromLocalFile(file, callback) {
|
|
|
+ var reader = new FileReader();
|
|
|
+ reader.onload = function(e) {
|
|
|
+ var data = e.target.result;
|
|
|
+ var workbook = XLSX.read(data, {type: 'binary'});
|
|
|
+ if(callback) callback(workbook);
|
|
|
+ };
|
|
|
+ reader.readAsBinaryString(file);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 读取 excel文件
|
|
|
+ function outputWorkbook(workbook) {
|
|
|
+ var sheetNames = workbook.SheetNames; // 工作表名称集合
|
|
|
+ sheetNames.forEach(name => {
|
|
|
+ var worksheet = workbook.Sheets[name]; // 只能通过工作表名称来获取指定工作表
|
|
|
+ for(var key in worksheet) {
|
|
|
+ // v是读取单元格的原始值
|
|
|
+ console.log(key, key[0] === '!' ? worksheet[key] : worksheet[key].v);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function readWorkbook(workbook) {
|
|
|
+ var sheetNames = workbook.SheetNames; // 工作表名称集合
|
|
|
+ var worksheet = workbook.Sheets[sheetNames[0]]; // 这里我们只读取第一张sheet
|
|
|
+ var csv = XLSX.utils.sheet_to_csv(worksheet);
|
|
|
+ document.getElementById('result').innerHTML = csv2table(csv);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将csv转换成表格
|
|
|
+ function csv2table(csv)
|
|
|
+ {
|
|
|
+ var html = '<table>';
|
|
|
+ var rows = csv.split('\n');
|
|
|
+ rows.pop(); // 最后一行没用的
|
|
|
+ rows.forEach(function(row, idx) {
|
|
|
+ var columns = row.split(',');
|
|
|
+ columns.unshift(idx+1); // 添加行索引
|
|
|
+ if(idx == 0) { // 添加列索引
|
|
|
+ html += '<tr>';
|
|
|
+ for(var i=0; i<columns.length; i++) {
|
|
|
+ html += '<th>' + (i==0?'':String.fromCharCode(65+i-1)) + '</th>';
|
|
|
+ }
|
|
|
+ html += '</tr>';
|
|
|
+ }
|
|
|
+ html += '<tr>';
|
|
|
+ columns.forEach(function(column) {
|
|
|
+ html += '<td>'+column+'</td>';
|
|
|
+ });
|
|
|
+ html += '</tr>';
|
|
|
+ });
|
|
|
+ html += '</table>';
|
|
|
+ return html;
|
|
|
+ }
|
|
|
+
|
|
|
+ function table2csv(table) {
|
|
|
+ var csv = [];
|
|
|
+ $(table).find('tr').each(function() {
|
|
|
+ var temp = [];
|
|
|
+ $(this).find('td').each(function() {
|
|
|
+ temp.push($(this).html());
|
|
|
+ })
|
|
|
+ temp.shift(); // 移除第一个
|
|
|
+ csv.push(temp.join(','));
|
|
|
+ });
|
|
|
+ csv.shift();
|
|
|
+ return csv.join('\n');
|
|
|
+ }
|
|
|
+
|
|
|
+ // csv转sheet对象
|
|
|
+ function csv2sheet(csv) {
|
|
|
+ var sheet = {}; // 将要生成的sheet
|
|
|
+ csv = csv.split('\n');
|
|
|
+ csv.forEach(function(row, i) {
|
|
|
+ row = row.split(',');
|
|
|
+ if(i == 0) sheet['!ref'] = 'A1:'+String.fromCharCode(65+row.length-1)+(csv.length-1);
|
|
|
+ row.forEach(function(col, j) {
|
|
|
+ sheet[String.fromCharCode(65+j)+(i+1)] = {v: col};
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return sheet;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
|
|
|
+ function sheet2blob(sheet, sheetName) {
|
|
|
+ sheetName = sheetName || 'sheet1';
|
|
|
+ var workbook = {
|
|
|
+ SheetNames: [sheetName],
|
|
|
+ Sheets: {}
|
|
|
+ };
|
|
|
+ workbook.Sheets[sheetName] = sheet;
|
|
|
+ // 生成excel的配置项
|
|
|
+ var wopts = {
|
|
|
+ bookType: 'xlsx', // 要生成的文件类型
|
|
|
+ bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
|
|
|
+ type: 'binary'
|
|
|
+ };
|
|
|
+ var wbout = XLSX.write(workbook, wopts);
|
|
|
+ var blob = new Blob([s2ab(wbout)], {type:"application/octet-stream"});
|
|
|
+ // 字符串转ArrayBuffer
|
|
|
+ function s2ab(s) {
|
|
|
+ var buf = new ArrayBuffer(s.length);
|
|
|
+ var view = new Uint8Array(buf);
|
|
|
+ for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
|
|
|
+ return buf;
|
|
|
+ }
|
|
|
+ return blob;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通用的打开下载对话框方法,没有测试过具体兼容性
|
|
|
+ * @param url 下载地址,也可以是一个blob对象,必选
|
|
|
+ * @param saveName 保存文件名,可选
|
|
|
+ */
|
|
|
+ function openDownloadDialog(url, saveName)
|
|
|
+ {
|
|
|
+ if(typeof url == 'object' && url instanceof Blob)
|
|
|
+ {
|
|
|
+ url = URL.createObjectURL(url); // 创建blob地址
|
|
|
+ }
|
|
|
+ var aLink = document.createElement('a');
|
|
|
+ aLink.href = url;
|
|
|
+ aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
|
|
|
+ var event;
|
|
|
+ if(window.MouseEvent) event = new MouseEvent('click');
|
|
|
+ else
|
|
|
+ {
|
|
|
+ event = document.createEvent('MouseEvents');
|
|
|
+ event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
|
|
+ }
|
|
|
+ aLink.dispatchEvent(event);
|
|
|
+ }
|
|
|
+
|
|
|
+ $(function() {
|
|
|
+ document.getElementById('file').addEventListener('change', function(e) {
|
|
|
+ var files = e.target.files;
|
|
|
+ if(files.length == 0) return;
|
|
|
+ var f = files[0];
|
|
|
+ if(!/\.xlsx$/g.test(f.name)) {
|
|
|
+ alert('仅支持读取xlsx格式!');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ readWorkbookFromLocalFile(f, function(workbook) {
|
|
|
+ readWorkbook(workbook);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ loadRemoteFile('./sample/test.xlsx');
|
|
|
+ });
|
|
|
+
|
|
|
+ function loadRemoteFile(url) {
|
|
|
+ readWorkbookFromRemoteFile(url, function(workbook) {
|
|
|
+ readWorkbook(workbook);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function exportExcel() {
|
|
|
+ var csv = table2csv($('#result table')[0]);
|
|
|
+ var sheet = csv2sheet(csv);
|
|
|
+ var blob = sheet2blob(sheet);
|
|
|
+ openDownloadDialog(blob, '2018级1班班级课表.xlsx');
|
|
|
+ }
|
|
|
+
|
|
|
+ function exportSpecialExcel() {
|
|
|
+ var aoa = [
|
|
|
+ ['主要调查内容', null, null, '其它信息'], // 特别注意合并的地方后面预留2个null
|
|
|
+ ['姓名', '性别', '成绩', '完成时间'],
|
|
|
+ ['小三', '男', 88, new Date()],
|
|
|
+ ['小四', '女', 99, new Date()],
|
|
|
+ ['八年级1班/2015班级课表'],
|
|
|
+ ['节次','星期一','星期二','星期三','星期四','星期五','星期六','星期天'],
|
|
|
+ ['第一节','08:35~09:20','08:00~08:45','08:00~08:45','08:00~08:45','08:00~08:45'],
|
|
|
+ ['数学(八下)','英语(八下)','生物(八下)','英语(八下)','语文(八下)'],
|
|
|
+ ];
|
|
|
+ var sheet = XLSX.utils.aoa_to_sheet(aoa);
|
|
|
+ sheet['!merges'] = [
|
|
|
+ // 设置A1-C1的单元格合并
|
|
|
+ {s: {r: 0, c: 0}, e: {r: 0, c: 2}}
|
|
|
+ ];
|
|
|
+ openDownloadDialog(sheet2blob(sheet), '单元格合并示例.xlsx');
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+</body>
|
|
|
+</html>
|