Skip to content

Instantly share code, notes, and snippets.

@qubaomingg
Created May 28, 2017 08:10
Show Gist options
  • Save qubaomingg/bd5e79bc44db9477fbfe007a891f4cd4 to your computer and use it in GitHub Desktop.
Save qubaomingg/bd5e79bc44db9477fbfe007a891f4cd4 to your computer and use it in GitHub Desktop.
let koaRequest = require('koa-request')
let _ = require('lodash')
let qs = require('qs')
let fs = require('fs')
let path = require('path');
let mime = require('mime');
let parse = require('co-body')
let util = require('./util')
const COOKIE = require('../config/config').cookie
// 下载相关
module.exports = {
/*
* @param
* opt{
* type {String}
* replacement {String}
* callback {Function}
* }
*/
requestAndWrite: function(opt) {
return function *(next) {
const ctx = this
let XLSX = require('xlsx')
let requestParam = this.request.query
if(!requestParam || !_.size(requestParam)) {
requestParam = yield parse(this, { limit: '100kb' })
}
// console.log(requestParam)
// console.log('====')
// send request get data.
let cookie = util.getCookie(this)
let ticket = this.cookies.get(COOKIE)
let url = util.getCommonPath({replacement: opt.replacement}, opt.url)
let requestData = opt.generatorPostParam && opt.generatorPostParam(requestParam)
if(opt.type != 'POST') {
url += `?&${qs.stringify(requestData)}`
}
// console.log(requestData)
let config = util.getCommonConfig({
ticket,
url,
cookie,
method: opt.type || 'GET',
data: requestData
})
// console.log(config)
let fileName = path.join(process.cwd(), '/exports', (requestParam.title || 'no_name.csv'))
// 如果没有exports目录则创建目录
if (!fs.existsSync(process.cwd() + '/exports/')){
fs.mkdirSync(process.cwd() + '/exports/');
}
let response = opt.url ? yield koaRequest(config) : {}
let fileContent = '';
// console.log(response.body)
// console.log('........')
try {
fileContent = JSON.parse(response.body)
} catch(e) {
fileContent = response.body
}
if(opt.formatContent) {
fileContent = opt.formatContent(fileContent, requestParam)
}
// console.log(fileName)
// console.log(fileContent)
// console.log('........')
function readFile(callback) {
if(fileName.indexOf('.xlsx') >= 0) {
XLSX.writeFileAsync(fileName, fileContent, writeCallBack.bind(this, fileName, ctx, callback))
} else {
var buffer = new Buffer([0xEF, 0xBB, 0xBF])
fileContent = buffer.toString("utf-8") + fileContent
fs.writeFile(fileName, fileContent, writeCallBack.bind(this, fileName, ctx, callback))
}
}
this.body = yield readFile;
yield * next;
}
},
// 浏览器出post请求,携带大量数据,node写入后返回文件给浏览器端。
postDataWrite: function(opt) {
return function *(next) {
const ctx = this;
let XLSX = require('xlsx')
let fileContent = ''
let postData = yield parse(this, { limit: '20kb' });
let fileName = 'exports/' + (postData.title || 'noname.xlsx')
// 如果没有exports目录则创建目录
if (!fs.existsSync(process.cwd() + '/exports/')){
fs.mkdirSync(process.cwd() + '/exports/');
}
try {
fileContent = JSON.parse(postData.content)
} catch (e) {
fileContent = postData.content
}
function saveFile(callback) {
if(fileName.indexOf('.xlsx') >= 0) {
XLSX.writeFileAsync(fileName, fileContent, writeCallBack.bind(this, fileName, ctx, callback))
} else {
var buffer = new Buffer([0xEF, 0xBB, 0xBF])
fileContent = buffer.toString("utf-8") + fileContent
fs.writeFile(fileName, fileContent, writeCallBack.bind(this, fileName, ctx, callback))
}
}
this.body = yield saveFile;
yield * next;
}
}
}
// helpers
function writeCallBack(fileName, ctx, callback, error) {
// writeFileAsync MD, 说好的回调呢,执行这里的时候文件还没写好....
setTimeout(function() {
ctx.set('Content-disposition', 'attachment;filename=' + encodeURIComponent(path.basename(fileName)));
ctx.type = mime.lookup(fileName);
ctx.body = fs.createReadStream(fileName);
fs.readFile(fileName, function (err, data) {
if (err) throw err;
// 过5s删除本文件,防止Node服务器磁盘爆了
setTimeout(function() {
fs.unlinkSync(fileName, function (err) {
if (err) throw err;
});
}, 5 * 1000);
callback(null, data);
});
}, 1000)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment