具体代码见:
一:导入功能
读取excel的多个sheet数据
<script type="text/javascript" src="js/xlsx.core.min.js"></script>
<table style="width:80%;margin-left:10%;margin-top:30px;">
<td align="right" style="width: 50%;">
<h3 align="center">导入参赛名单:</h3>
</td>
<td align="left" style="width: 50%;">
<input type="file" id="uploadfile" onchange="importf(this);"/>
</td>
</table>
<div style="width:80%;margin-left:10%;margin-top:30px;">
<div style="width:30%;height:100%;float:left;">
<table id="txtArea1" style="width:100%;" cellspacing="0" cellpadding="0"> </table>
</div>
<div style="width:30%;height:100%;margin-left:5%;margin-right:5%;float:left;">
<table id="txtArea2" style="width:100%;" cellspacing="0" cellpadding="0"> </table>
</div>
<div style="width:30%;height:100%;float:left;">
<table id="txtArea3" style="width:100%;" cellspacing="0" cellpadding="0"> </table>
</div>
</div>
js代码:
<script type="text/javascript">
// 遍历每张表读取
var persons1 = [];
var persons2 = [];
var persons3 = [];
function importf(obj) {
var wb;// 读取完成的数据
var f = obj.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
wb = XLSX.read(data, {
type : 'binary'
}); // 以二进制流方式读取得到整份excel表格对象
// 表格的表格范围,可用于判断表头是否数量是否正确
var fromTo = '';
// wb.SheetNames[0]是获取Sheets中第一个Sheet的名字
// wb.Sheets[Sheet名]获取第一个Sheet的数据JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]));
for (var i = 0; i < wb.SheetNames.length; i++) {
if (wb.Sheets.hasOwnProperty(wb.SheetNames[i])) {
fromTo = wb.Sheets[wb.SheetNames[i]]['!ref']; // output: A1:D5
if(i==0){
persons1 = persons1.concat(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[i]]));
}else if(i==1){
persons2 = persons2.concat(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[i]]));
}else if(i==2){
persons3 = persons3.concat(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[i]]));
}
//break; //如果只取第一张表,就加上这行
}
}
//document.getElementById("txtArea1").innerHTML= JSON.stringify(persons1)+JSON.stringify(persons2)+JSON.stringify(persons3);
appendTr("txtArea1",persons1);
appendTr("txtArea2",persons2);
appendTr("txtArea3",persons3);
};
reader.readAsBinaryString(f);
}
function appendTr(id, array){
if(array.length>0){
for(var i = 0; i < array.length; i++){
o=document.createElement("TR"); //<td align="center" width="20%" class="cx-nr"><%=orgname%></td>
// 所属公司
o1=document.createElement("TD");
o1.innerHTML=array[i].所属公司;
o1.setAttribute("align","center");
o1.setAttribute("width","50%");
o1.setAttribute("class","cx-nr");
// 参赛人员
o2=document.createElement("TD");
o2.innerHTML=array[i].参赛人员;
o2.setAttribute("align","center");
o2.setAttribute("width","50%");
o2.setAttribute("class","cx-nr1");
o.appendChild(o1);
o.appendChild(o2);
document.getElementById(id).appendChild(o);
}
}
}
</script>
二:导出功能
var json;
var tmpdata;//?
var tmpdata1 = [];
var tmpdata2 = [];
var tmpdata3 = [];
var outputPos1;
var outputPos2;
var outputPos3;
var json1;
var json2;
var json3;
function getJson(num){
var tabLen = document.getElementById("jinji"+num);
var jsonStr = "[";
for (var i = 1; i < tabLen.rows.length; i++) {
jsonStr += '{"十六强":"' + tabLen.rows[i].cells[0].innerHTML + '","八强":"' + tabLen.rows[i].cells[1].innerHTML + '","四强":"' + tabLen.rows[i].cells[2].innerHTML + '"},'
}
jsonStr= jsonStr.substr(0, jsonStr.length - 1);
jsonStr += "]";
if(num==1) json1 = JSON.parse(jsonStr); //将json字符串转换为json数组
if(num==2) json2 = JSON.parse(jsonStr); //将json字符串转换为json数组
if(num==3) json3 = JSON.parse(jsonStr); //将json字符串转换为json数组
}
function getTmpdataOutputPos(num){
if(num==1){json=json1; tmpdata = json1[0]; json1.unshift({});}
if(num==2){json=json2; tmpdata = json2[0]; json2.unshift({});}
if(num==3){json=json3; tmpdata = json3[0]; json3.unshift({});}
//var tmpdata = json[0];
//json.unshift({});
var keyMap = []; //获取keys
for (var k in tmpdata) {
keyMap.push(k);
json[0][k] = k;
}
if(num==1){
tmpdata1 = [];//用来保存转换好的json
json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
v: v[k],
position: (j > 25 ? getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
}))).reduce((prev, next) => prev.concat(next)).forEach((v, i) => tmpdata1[v.position] = {
v: v.v
});
outputPos1 = Object.keys(tmpdata1); //设置区域,比如表格从A1到D10
}else if(num==2){
tmpdata2 = [];//用来保存转换好的json
json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
v: v[k],
position: (j > 25 ? getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
}))).reduce((prev, next) => prev.concat(next)).forEach((v, i) => tmpdata2[v.position] = {
v: v.v
});
outputPos2 = Object.keys(tmpdata2); //设置区域,比如表格从A1到D10
}else if(num==3){
tmpdata3 = [];//用来保存转换好的json
json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
v: v[k],
position: (j > 25 ? getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
}))).reduce((prev, next) => prev.concat(next)).forEach((v, i) => tmpdata3[v.position] = {
v: v.v
});
outputPos3 = Object.keys(tmpdata3); //设置区域,比如表格从A1到D10
}
}
var tmpDown; //导出的二进制对象
function PromotionTeamToExcel(type) {
getJson(1); //女单
getJson(2); //男单
getJson(3); //混双
var uploadfile2 = document.getElementById("uploadfile2").value;
var filename = uploadfile2.substring(uploadfile2.lastIndexOf("\\")+1);
document.getElementById("hf").download=filename;
getTmpdataOutputPos(1); //json1
getTmpdataOutputPos(2); //json2
getTmpdataOutputPos(3); //json3
var tmpWB = {
SheetNames: ['女单晋级','男单晋级','混双晋级'], //保存的表标题
Sheets: {
'女单晋级': Object.assign({},
tmpdata1, //内容
{
'!ref': outputPos1[0] + ':' + outputPos1[outputPos1.length - 1] //设置填充区域
}),
'男单晋级': Object.assign({},
tmpdata2, //内容
{
'!ref': outputPos2[0] + ':' + outputPos2[outputPos2.length - 1] //设置填充区域
}),
'混双晋级': Object.assign({},
tmpdata3, //内容
{
'!ref': outputPos3[0] + ':' + outputPos3[outputPos3.length - 1] //设置填充区域
})
}
};
tmpDown = new Blob([s2ab(XLSX.write(tmpWB,
{bookType: (type == undefined ? 'xlsx':type),bookSST: false, type: 'binary'}//这里的数据是用来定义导出的格式类型
))], {
type: ""
}); //创建二进制对象写入转换好的字节流
var href = URL.createObjectURL(tmpDown); //创建对象超链接
document.getElementById("hf").href = href; //绑定a标签
document.getElementById("hf").click(); //模拟点击实现下载
setTimeout(function() { //延时释放
URL.revokeObjectURL(tmpDown); //用URL.revokeObjectURL()来释放这个object URL
}, 100);
}
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;
}
// 将指定的自然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。
function getCharCol(n) {
let temCol = '',
s = '',
m = 0
while (n > 0) {
m = n % 26 + 1
s = String.fromCharCode(m + 64) + s
n = (n - m) / 26
}
return s
}
补充1:合并单元格,但是设置单元格样式无效
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="http://oss.sheetjs.com/js-xlsx/xlsx.full.min.js"></script>
<script>
//如果使用 FileSaver.js 就不要同时使用以下函数
function saveAs(obj, fileName) {
//当然可以自定义简单的下载文件实现方式
var tmpa = document.createElement("a");
tmpa.download = fileName || "下载";
tmpa.href = URL.createObjectURL(obj); //绑定a标签
tmpa.click(); //模拟点击实现下载
setTimeout(function () { //延时释放
URL.revokeObjectURL(obj); //用URL.revokeObjectURL()来释放这个object URL
}, 100);
}
var json = [{ //测试数据
"分组": 1,//A
"所属公司": "aa",
"参赛人员": "bb"
}, {
"分组": 2,
"所属公司": "cc",
"参赛人员": "dd"
}, {
"分组": 3,
"所属公司": "ee",
"参赛人员": "ff"
}];
const wopts = { bookType: 'xlsx', bookSST: true, type: 'binary' };//这里的数据是用来定义导出的格式类型
function downloadExl(type) {
var wb = { SheetNames: ['Sheet1'], Sheets: {}, Props: {} };
//wb.Sheets['Sheet1'] = XLSX.utils.json_to_sheet(json);//通过json_to_sheet转成单页(Sheet)数据
json = XLSX.utils.json_to_sheet(json);
json["A2"] = { t: "s", v: "A组" };
json["!merges"] = [{//合并第一列数据[A2,A3,A4,A5]
s: {//s为开始
c: 0,//开始列
r: 1//开始行
}, e: {//e结束
c: 0,//结束列
r: 4//结束行
}
}];
wb.Sheets['Sheet1'] = json;
saveAs(
new Blob([s2ab(XLSX.write(wb, wopts))], { type: "application/octet-stream"}),
"这里是下载的文件名" + '.' + (wopts.bookType == "biff2" ? "xls" : wopts.bookType));
}
function s2ab(s) {
if (typeof ArrayBuffer !== 'undefined') {
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;
} else {
var buf = new Array(s.length);
for (var i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
}
</script>
<button onclick="downloadExl()">导出</button>
</body>
</html>
补充2:合并单元格,可以设置单元格的宽度、居中、字体、颜色等
下载protobi/js-xlsx:https://github.com/protobi/js-xlsx
将js-xlsx-master\dist\xlsx.full.min.js放到js目录中
<script type="text/javascript" src="js/xlsx.full.min.js"></script>
<input type="button" onclick="PromotionTeamToExcel();" value="导出为Excel"/>
var resGroup = ["A组","B组","C组","D组","E组","F组","G组","H组"];
function saveAs(obj, fileName) {
var tmpa = document.createElement("a");
tmpa.download = fileName || "下载";
tmpa.href = URL.createObjectURL(obj);
tmpa.click();
setTimeout(function () {
URL.revokeObjectURL(obj);
}, 100);
}
const wopts = { bookType: 'xlsx', bookSST: true, type: 'binary', cellStyles: true };
function PromotionTeamToExcel(type) {
var jsonStr = "[";
for (var i = 0; i < result.length; i++) {
jsonStr += '{"分组":"","所属公司":"' + $('#t'+i+'-1').text() + '","参赛人员":"' + $('#t'+i+'-2').text() + '"},'
}
jsonStr= jsonStr.substr(0, jsonStr.length - 1);
jsonStr += "]";
var json = JSON.parse(jsonStr); //将json字符串转换为json数组
var tmpdata = json[0];
json.unshift({});
var keyMap = []; //获取keys
for (var k in tmpdata) {
keyMap.push(k);
json[0][k] = k;
}
var tmpdata = [];//用来保存转换好的json
json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {v: v[k], position: (j > 25 ? getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
}))).reduce((prev, next) => prev.concat(next)).forEach((v, i) => tmpdata[v.position] = {v: v.v});
var outputPos = Object.keys(tmpdata); //设置区域,比如表格从A1到D10
//t = [[2,5],[6,9],[10,13],[14,17],[18,21],[22,25],[26,28],[29,31]];
//t = [[2,5],[6,9],[10,13],[14,17],[18,21],[22,24],[25,27],[28,30]];
//t = [[2,5],[6,9],[10,13],[14,17],[18,20],[21,23],[24,26],[27,29]];
//t = [[2,5],[6,9],[10,13],[14,16],[17,19],[20,22],[23,25],[26,28]];
//t = [[2,5],[6,9],[10,12],[13,15],[16,18],[19,21],[22,24],[25,27]];
//t = [[2,5],[6,8],[9,11],[12,14],[15,17],[18,20],[21,23],[24,26]];
var end = 0;
var t = [];
for(var i = 0; i < 8; i++){
// 分组
if(end < ((result.length%8)*4+1)){
end = 4*(i+1)+1;
t[i] = [end-3,end];
}else{
end = end+3;
t[i] = [end-2,end];
}
}
//列的宽度
tmpdata["!cols"] = [{wpx: 80}, {wpx: 160}, {wpx: 160}];
//合并单元格
var merges=[];
for(var i = 0; i < 8; i++){
merges.push({s: {c: 0, r: t[i][0]-1}, e: {c: 0, r: t[i][1]-1}});
}
tmpdata["!merges"] = merges;
//每个合并单元格的数据
for(var i = 0; i < 8; i++){
tmpdata["A"+t[i][0]] = { t: "s", v: resGroup[i], s: {alignment: {horizontal: "center", vertical: "center"} } };
}
//设置单元格居中显示
for(var i = 0; i < result.length; i++){
var ii=i+2;
tmpdata["B"+ii].s = {alignment: {horizontal: "center", vertical: "center"} };
tmpdata["C"+ii].s = {alignment: {horizontal: "center", vertical: "center"} };
}
//设置标题字体、加粗、居中
tmpdata["A1"].s = {font: { sz: 13, bold: true, }, alignment: {horizontal: "center", vertical: "center", wrap_text:true} };//<====设置xlsx单元格样式
tmpdata["B1"].s = {font: { sz: 13, bold: true, }, alignment: {horizontal: "center", vertical: "center", wrap_text:true} };//<====设置xlsx单元格样式
tmpdata["C1"].s = {font: { sz: 13, bold: true, }, alignment: {horizontal: "center", vertical: "center", wrap_text:true} };//<====设置xlsx单元格样式
var tmpWB = {
SheetNames: ['sheet1'], //保存的表标题
Sheets: {
'sheet1': Object.assign({}, tmpdata, {
'!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] //设置填充区域
})
}
};
tmpDown = new Blob([s2ab(XLSX.write(tmpWB, { bookType: (type == undefined ? 'xlsx' : type), bookSST: false, type: 'binary' }))], {type: ""});
saveAs(tmpDown, title + '.' + (wopts.bookType == "biff2" ? "xls" : wopts.bookType));
}
function getCharCol(n) {
let temCol = '',
s = '',
m = 0
while (n > 0) {
m = n % 26 + 1
s = String.fromCharCode(m + 64) + s
n = (n - m) / 26
}
return s;
}
function s2ab(s) {
if (typeof ArrayBuffer !== 'undefined') {
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;
} else {
var buf = new Array(s.length);
for (var i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
}