最近在做项目的时候需要这样一个模块,让用户上传excel文件导入姓名和电话号码,可以在线预览。
之后就开始琢磨要怎么实现。
首先这样的流程:前端----后台----存储----读取----传回前端json格式。
然后我把这个流程简化成几个难点:
1.前端怎么操作文件?
2.前端怎么发至后台?
3.后台如何接收文件?
4.后台怎么读取excel文件?
正文:
1.前端怎么操作文件?
h5有自己的文件操作系统,File API,网上有很多资源,以下是一段最简洁的代码:
- <form id="uploadForm" enctype="multipart/form-data">
- <p>上传文件:<input type="file" name="file" id="ff" /></p>
- <input type="button" value="上传" onclick="doUpload()" />
- </form>
最为关键是的把form的entype设置为multipart/form-data,该类型就是为传文件而服务的。
2.前端怎么发至后台存储?
前端发送文件最简单的就是jquery封装的ajax方法,以下为doUpload()函数的具体代码:
- function doUpload() {
- var formData = new FormData($("#uploadForm")[0]);
- if($('#ff').val() !== ''){
- $.ajax({
- url: '',
- 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里你会看到以下这些内容
说明已经传送到了后台API。
3.后台如何接收文件?
查阅很多资料之后找到一个叫做connect-busboy的模块可以进行文件传输。
安装模块
- npm install connect-busboy
使用模块
nodejs启动页
- var busboy = require('connect-busboy');
中间件配置
- app.use(busboy({
- limits: {
- fileSize: 10 * 1024 * 1024
- }
- }));
需要引入的模块
- 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('写入完成');
-
- });
- });
- 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);
-
- 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};
- exceltext.push({name:cell.w,phone:cell1.w});
- }
- } catch (err) {
- res.send(exceltext);
- }
- }
这样整套流程就做完了。
我相信肯定有很多前端开发者和我一样都厌倦了修改完代码再切换到浏览器刷新去看新的实现。今天我们就用一种最简单的文件监听模式和一个gulp插件(gulp-livereload)来实现这个功能。
- 首先安装gulp
npm install gulp -g
- 安装gulp-livereload插件
npm i gulp-livereload --save-dev
(npm i 为npm install 缩写)
3. 配置gulp配置文件
自动刷新配置
gulp.task('watch', function () {
livereload.listen();
gulp.watch(['dist/**']).on('change', livereload.changed);
});
要使这个能够工作,还需要在浏览器上安装LiveReload插件,或者在你需要自动刷新的页面上加上
1.本地
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>')</script>
2.远程
<script src="http://192.168.0.1:35729/livereload.js?snipver=1"></script>
整个gulp
var gulp = require('gulp');
var less = require('gulp-less');
var minifyCSS = require('gulp-minify-css');
var babel = require('gulp-babel');
var livereload = require('gulp-livereload');
//编译less
gulp.task('less', function () {
return gulp.src('./src/less/**.less')
.pipe(less())
//.pipe(minifyCSS())
.pipe(gulp.dest('dist/css'));
});
//监听less文件
gulp.task('autoless', function () {
gulp.watch('./src/less/**.less', ['less'])
})
//编译es6
gulp.task('babel', () => {
return gulp.src(['./src/js/**.js'])
.pipe(babel({ presets: ['es2015'] }))
.pipe(gulp.dest('dist/js'));
});
//监听js文件
gulp.task('autojs', function () {
gulp.watch('./src/js/**.js', ['babel'])
});
//监听所有打包之后的文件变动,自动刷新页面
gulp.task('watch', function () {
// Create LiveReload server
livereload.listen();
// Watch any files in dist/, reload on change
gulp.watch(['dist/**']).on('change', livereload.changed);
});
// 使用 gulp.task('default') 定义默认任务
gulp.task('default', ['less', 'autoless', 'babel', 'autojs',