最近在做一些项目,开始频繁的处理一些上传文件和导出excel的需求,现在就 egg.js 接收文件处理做一点简单的总结。
File 模式
1 2 3
| exports.multipart = { mode: 'file', };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const Controller = require('egg').Controller; const fs = require('mz/fs');
module.exports = class extends Controller { async upload() { const { ctx } = this; const file = ctx.request.files[0]; const name = 'egg-multipart-test/' + path.basename(file.filename); let result; try { result = await ctx.oss.put(name, file.filepath); } finally { await fs.unlink(file.filepath); } ctx.body = { url: result.url, requestBody: ctx.request.body, }; } };
|
对于多文件, 通过 ctx.request.files 属性进行遍历,分别处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const Controller = require('egg').Controller; const fs = require('mz/fs');
module.exports = class extends Controller { async upload() { const { ctx } = this; console.log(ctx.request.body); for (const file of ctx.request.files) { console.log('field: ' + file.fieldname); console.log('filename: ' + file.filename); console.log('encoding:' + file.encoding); console.log('mime:' + file.mime); console.log('tmp filepath:' + file.filepath); let result; try { result = await ctx.oss.put('egg-multipart-test/' + file.filename, file.filepath); } finally { await fs.unlink(file.filepath); } } } }
|
Stream模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| const path = require('path'); const sendToWormhole = require('stream-wormhole'); const Controller = require('egg').controller;
class UploaderController extends Controller { async upload() { const ctx = this.ctx; const stream = await ctx.getFileStream(); const name = 'egg-multipart-test/' + path.basename(stream.filename); let result; try { result = await ctx.oss.put(name, stream); } catch (err) { await sendToWormhole(stream); throw err; } ctx.body = { url: result.url, fields: stream.fields, }; } }
module.exports = UploaderController;
stream = await ctx.getFileStream({ requireFile: false, }); const buffers = []; let buffer; let res; const { status, userName } = stream.fields;
|
通过 ctx.getFileStream 获取用户上传文件,需要满足两个条件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| const sendToWormhole = require('stream-wormhole'); const Controller = require('egg').Controller;
class UploaderController extends Controller { async upload() { const ctx = this.ctx; const parts = ctx.multipart(); let part; while ((part = await parts()) != null) { if (part.length) { console.log('field: ' + part[0]); console.log('value: ' + part[1]); console.log('valueTruncated: ' + part[2]); console.log('fieldnameTruncated: ' + part[3]); } else { if (!part.filename) { return; } console.log('field: ' + part.fieldname); console.log('filename: ' + part.filename); console.log('encoding: ' + part.encoding); console.log('mime: ' + part.mime); let result; try { result = await ctx.oss.put('egg-multipart-test/' + part.filename, part); } catch (err) { await sendToWormhole(part); throw err; } console.log(result); } } console.log('and we are done parsing the form!'); } }
module.exports = UploaderController;
|
实战
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| const sendToWormhole = require('stream-wormhole'); const XLSX = require('xlsx');
class UploaderController extends Controller { async uploadFile() { const { ctx } = this; try { const stream = await ctx.getFileStream(); const buffers = []; const { type,userName } = stream.fileds; let res; await new Promise(resolve => { stream.on('data', chunk => { buffers.push(chunk); }).on('end', () => { buffer = Buffer.concat(buffers); const workbook = XLSX.read(buffer, { type: 'buffer' }); const sheetName = workbook.SheetNames; res = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], { raw: true, header: 1, }); resolve(); }).on('error', err => { throw err; }) }); } catch (er) { throw err; } } }
|