1、问题描述
最近在做报表导入数据库的需求,报表文件为excel里面有多个sheet。
2、解决方法
- 使用FileReader异步读取上传的文件。
- 使用sheet.js进行excel表格内容的解析。
- 使用bootstrap.js的tab组件对上传的表格进行一个页面预览的展示。
3、参考代码
ImportReportForm.asp
<%Response.Charset="GB2312"%>
<script type="text/javascript" charset="utf-8" src="/root/js/xlsx.full.min.js"></script>
<script src="/root/js/jquery.min.js"></script>
<script src="/root/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/root/css/bootstrap.min.css">
<script type="text/javascript">
$(document).ready(function (){
$("#BtnOK").click(function(){
var fileInput=$("#uploadfile")
parseFile(fileInput[0].files[0])
});
function parseFile(file){
console.log(file)
var rABS = FileReader.prototype.readAsArrayBuffer;
var filereader=new FileReader()
filereader.onload=function(){ //回调函数
var data = this.result;
console.log(data);
var workbook=XLSX.read(data, {type: rABS ? 'binary' : 'array',dateNF: "yyyy-mm-dd",cellDates:true,cellStyles:true})
$("#btn0").text(workbook.SheetNames[0])
$("#btn1").text(workbook.SheetNames[1])
$("#btn2").text(workbook.SheetNames[2])
$("#tab0").html(XLSX.utils.sheet_to_html(workbook.Sheets[workbook.SheetNames[0]]))
$("#tab1").html(XLSX.utils.sheet_to_html(workbook.Sheets[workbook.SheetNames[1]]))
$("#tab2").html(XLSX.utils.sheet_to_html(workbook.Sheets[workbook.SheetNames[2]]))
$("#sheet0").val(JSON.stringify(XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]],{header:1})));
$("#sheet1").val(JSON.stringify(XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[1]],{header:1})));
$("#sheet2").val(JSON.stringify(XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[2]],{header:1})));
}
if(rABS) {
filereader.readAsBinaryString(file)
}else{
filereader.readAsArrayBuffer(file)
}
}
$("#btnImport").click(function () {
var i=0;
for(i=0;i<3;i++){
var sSheetName=$("#btn"+i).text();
var json = $.parseJSON("{\"content\":" + $("#sheet"+i).val() + "}");
var content = json["content"];
console.log(content)
importDetail(sSheetName,content)
}
});
function importDetail(sSheetName,sContent){
var sDetailContent;
var j=1;
//row表示excel中每个sheet内容的行数。因为我这里每个sheet的内容有6行,所以这里row设置为6,当然如果你不能确定每个sheet内容会有几行的话,直接设置一个很大的数,比如:60,600也是可以的
var row=6;
while (j<=sContent.length) {
sDetailContent="";
for(var k=1;k<=row;k++){
if(j>sContent.length){
break;
}
if (sDetailContent==""){
sDetailContent = sDetailContent + JSON.stringify(sContent[j-1]);
}
else{
sDetailContent = sDetailContent + "," + JSON.stringify(sContent[j-1]);
}
j++;
}
sDetailContent="[" + sDetailContent + "]";
$.ajax({
url:"ImportReport.asp",
type:"POST",
async: false,
data:{
SheetName: escape(sSheetName),
Content:escape(sDetailContent)
},
dataType:"text",
success:function(data){
},
error: function(data){
}
})
}
}
});
</script>
<div>
<form id="uploadForm" name="uploadForm">
上传文件:<input type="file" name="uploadfile" id="uploadfile" value="uploadfile" />
</form>
<button id="BtnOK" name="BtnOK" class="btn ">确定</button>
<br/><br/><br/>
<button type="button" id="btnImport" class="btn" >导入</button>
</div>
<div>
<ul id="myTab" class="nav nav-tabs">
<li>
<a href="#tab0" data-toggle="tab" id="btn0">
</a>
</li>
<li>
<a href="#tab1" data-toggle="tab" id="btn1">
</a>
</li>
<li>
<a href="#tab2" data-toggle="tab" id="btn2">
</a>
</li>
</ul>
</div>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in active" id="tab0">
</div>
<div class="tab-pane fade " id="tab1">
</div>
<div class="tab-pane fade" id="tab2">
</div>
</div>
<input type="hidden" id="sheet0" name="sheet0" value=""/>
<input type="hidden" id="sheet1" name="sheet1" value=""/>
<input type="hidden" id="sheet2" name="sheet2" value=""/>
ImportReport.asp
<%
Response.Charset="GB2312"
sSheetName = unescape(Request("SheetName"))
sContent = unescape(Request("Content"))
Response.write "sSheetName="&sSheetName&"<br/>"
Response.write "sContent="&sContent&"<br/>"
%>
4、运行结果
先选择要上传的文件
点击“确定”,FileReader获取上传的文件的内容,sheetjs把FileReader获取到的文件内容渲染到页面上。
点击“导入”按钮,使用$.parseJSON把excel每个sheet中的内容转为json数组。把这个转换好的数组传到后端进行处理就行了。
5、总结
因为只要得到了那个转换好的数组,后端再进行一个数组的解析和入库这个就很简单了,所以我就没写后端的处理代码。因为目前开发的需求许多地方要等用户回复确认,比如那个报表导入模板什么的。之前也研究了一下报表导入功能的实现并且现在正好手头空闲下来了,就忙里偷闲记录一下了。
感觉原生js直接操作dom确实很麻烦的。
上框架会方便不少,不过前提是你要熟悉dom。
6、参考资料
FileReader - Web API 接口参考 | MDN (mozilla.org)
Reading Files | SheetJS Community Edition
js使用xlsx读取excel文件_茯神_fushen的博客-CSDN博客