最近在做项目的时候需要这样一个模块,让用户上传excel文件导入姓名和电话号码,可以在线预览。
之后就开始琢磨要怎么实现。
首先这样的流程:前端----后台----存储----读取----传回前端json格式。
然后我把这个流程简化成几个难点:
1.前端怎么操作文件?
2.前端怎么发至后台?
3.后台如何接收文件?
4.后台怎么读取excel文件?
正文:
1.前端怎么操作文件?
h5有自己的文件操作系统,File API,网上有很多资源,以下是一段最简洁的代码:
最为关键是的把form的entype设置为multipart/form-data,该类型就是为传文件而服务的。
2.前端怎么发至后台存储?
前端发送文件最简单的就是jquery封装的ajax方法,以下为doUpload()函数的具体代码:
function doUpload() {
var formData = new FormData($("#uploadForm")[0]);
if($('#ff').val() !== ''){
$.ajax({
url: '',//此处放你自己的后台API
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function(returndata) {
alert(returndata);
},
error: function(returndata) {
alert(returndata);
}
});
}else{
alert('请选择文件。')
}
}
右键打开‘检查’然后点开Network这一栏,然后选取文件点击上传之后会多出一栏formdata 点开它,在Headers里你会看到以下这些内容
3.后台如何接收文件?
查阅很多资料之后找到一个叫做connect-busboy的模块可以进行文件传输。
安装模块
npm install connect-busboy
使用模块
nodejs启动页
var busboy = require('connect-busboy');
中间件配置
app.use(busboy({
limits: {
fileSize: 10 * 1024 * 1024 // 10MB
}
}));
需要引入的模块
var Busboy = require('connect-busboy');
var path = require('path');
var fs = require('fs');
然后就可以使用了
router.post('/formdata', function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");//允许跨域请求
req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
var tmp_path = path.join(__dirname, path.basename(filename));//存储路径
var ws = fs.createWriteStream(tmp_path);
file.pipe(ws);
console.log(tmp_path);
file.on('end', function() {
console.log('file end');
});
ws.on('finish',function(){
console.log('写入完成');
//test(req,res,next,tmp_path);这段是之后用来处理excel文件的函数
});
});
req.pipe(req.busboy);
});
这样你就可以将前端传输的文件存储在了后台。
4.后台怎么读取excel文件?
这个时候又需要一个叫做xlsx的模块。
安装
npm install xlsx
使用
var xlsx = require('xlsx');
以下是读取文件并传回json的函数
function test(req, res, next, mypath) {
var workbook = xlsx.readFileSync(mypath);//读取刚存完的excel文件
var firstSheetName = workbook.SheetNames[0];
var sheet = workbook.Sheets[firstSheetName];
var cell = '1';
var r = 0,
c = 0,
exceltext = new Array,
count = new Object;
try {
while (cell !== undefined) {
var row = xlsx.utils.encode_row(r);//行
var col = xlsx.utils.encode_col(c);//第一列
var col1 = xlsx.utils.encode_col(c + 1);//第二列
var addr = col + row;
var addr1 = col1 + row;
var cell = sheet[addr];//读取此行第一列的数据,姓名
var cell1 = sheet[addr1];//读取此行第二列的数据,电话号码
r++;//一次读取下一行
exceltext[n - 1] = {name:cell.w,phone:cell1.w};//将数据存到数组里
}
} catch (err) {
res.send(exceltext);//传回json数据
}
}
这样整套流程就做完了。
遇到一个很奇怪的问题,数组内要传值而不是对象名,如果通过循环添加的话,就会造成数组内所有对象都是最后一个对象的值
var aa = new Array,
bb = new Object,
i = 0;
for(i = 0; i < 10; i++){
bb.name = i;
aa.push(bb);
}
console.log(aa);
有兴趣的同学可以测试一下这段代码。