热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NodejsExpress下载文件,并保存成原文件

现时需要开发一个Excel下载功能后台有一个API,负责接收传入的JSON文件,生成带图片的Excel文件在临时目录(生成Excel使用npmexceljs库),并将文件通过Router返回前台Cl

现时需要开发一个Excel下载功能

后台有一个API,负责接收传入的JSON文件,生成带图片的Excel文件在临时目录(生成Excel使用npm exceljs库),并将文件通过Router返回

前台Client调用后台API,读取文件流生成Excel文件下载

 

 

API生成Excel文件代码

const getLinePlanExcelJson = (data) => {
// let workBook;
//workbook properties
var workBook = new exceljs.Workbook();
workBook.creator
= 'Esquel LPD Project';
workBook.lastModifiedBy
= 'Esquel LPD Project';
workBook.created
= new Date();
workBook.modified
= new Date();


return new Promise((resolve, reject) => {
if (typeof (data.customerCode) === 'undefined' || typeof (data.linePlanProducts) === 'undefined') {
reject(
new Error('{"Error Message":"incorrect format."}'));
}

//base var
let mc_productStyles = data.productStyles;
let mc_productFabrics
= data.productFabrics;
let mc_productTrims
= data.productTrims;

//---------------------------
let workSheet_name = "LinePlan";

// create worksheet
let workSheet = workBook.addWorksheet(workSheet_name, {
// properties: {
// tabColor: { argb: 'FFC0000' }
// },
// pageSetup: {
// paperSize: 50,
// orientation: 'landscape'
// }
});


//setting header title
let headerTitleArray = config.LinePlan.columns;
let headerColumns
= [];
for (let headerIndex = 0; headerIndex ) {
headerColumns.push({
header: headerTitleArray[headerIndex].title,
key: 'col' + headerIndex,
width: headerTitleArray[headerIndex].width
});
}
//setting header to worksheet
workSheet.columns = headerColumns;

//setting auto filter
workSheet.autoFilter = {
from: 'A1',
to:
'AA1'
}
//----------------------------------------------------

//col index
let colIndex = 1;
let rowIndex
= 1;

data.linePlanProducts.map((linePlanProduct)
=> {

//get style data
let find_StyleData = _.where(mc_productStyles, { styleID: linePlanProduct.productID });

linePlanProduct.productMaterialConfigs.map((colorway)
=> {
//reset col index
colIndex = 1;
let newrow
= [];

//style id---------------------------------------
newrow[colIndex] = linePlanProduct.productID;

//style image---------------------------------------
colIndex++;
newrow[colIndex]
= find_StyleData[0].imageURL ? find_StyleData[0].imageURL : '';
// cell = { v: find_StyleData[0].imageURL, t: 's', l: { Target: find_StyleData[0].imageURL, Tooltip: linePlanProduct.productID } };

// //colorway body fabirc image---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.PrimaryFabricImageUrl ? colorway.PrimaryFabricImageUrl : '';
// cell = { v: colorway.PrimaryFabricImageUrl, t: 's', l: { Target: colorway.PrimaryFabricImageUrl, Tooltip: colorway.primaryFabricID } };

//matching---------------------------------------
colIndex++;

//colorway body fabirc item code---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.primaryFabricID;

//colorway body fabirc info---------------------------------------
let find_FabricData = _.where(mc_productFabrics, { fabricID: colorway.primaryFabricID });
colIndex
++;
newrow[colIndex]
= find_FabricData[0].longDescriptions[1] ? find_FabricData[0].longDescriptions[1] : '';


// //colorway body fabirc content---------------------------------------
colIndex++;
newrow[colIndex]
= find_FabricData[0].longDescriptions[2] ? find_FabricData[0].longDescriptions[2] : '';

// //fabric width---------------------------------------
colIndex++;
newrow[colIndex]
= find_FabricData[0].longDescriptions[4] ? find_FabricData[0].longDescriptions[4] : '';


//button colour---------------------------------------
colIndex++;

// // let find_trims = _.where(colorway.appliedAuxiliaries, { auxiliaryType: 'T' });
// // let find_fabrics = _.where(colorway.appliedAuxiliaries, { auxiliaryType: 'F' });

// //button1 item code---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.appliedAuxiliaries[0] ? colorway.appliedAuxiliaries[0].auxiliaryID : '';

//button2 item code---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.appliedAuxiliaries[1] ? colorway.appliedAuxiliaries[1].auxiliaryID : '';

//button3 item code---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.appliedAuxiliaries[2] ? colorway.appliedAuxiliaries[2].auxiliaryID : '';

//button4 item code---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.appliedAuxiliaries[3] ? colorway.appliedAuxiliaries[3].auxiliaryID : '';


// //style fit---------------------------------------
colIndex++;
newrow[colIndex]
= linePlanProduct.fitName;

//style collection---------------------------------------
colIndex++;
newrow[colIndex]
= linePlanProduct.collectionName ? linePlanProduct.collectionName + ' Collection' : '';

//style gender---------------------------------------
colIndex++;
newrow[colIndex]
= linePlanProduct.gender;

//fabric---------------------------------------
colIndex++;
newrow[colIndex]
= find_FabricData[0].longDescriptions[0] ? find_FabricData[0].longDescriptions[0] : '';


//style collar---------------------------------------
colIndex++;
newrow[colIndex]
= linePlanProduct.collarName;

//style sleeve---------------------------------------
colIndex++;
newrow[colIndex]
= linePlanProduct.sleeveName;


//style cuff---------------------------------------
colIndex++;
newrow[colIndex]
= linePlanProduct.cuffName;

//style washing---------------------------------------
colIndex++;

//style pocket---------------------------------------
colIndex++;
newrow[colIndex]
= linePlanProduct.pocketName;

//colorway body pattern pocket---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.bodyPattern;

//colorway body color name---------------------------------------
colIndex++;

//colorway name---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.colorway;

//colorway plu---------------------------------------
colIndex++;
newrow[colIndex]
= colorway.pluNumber

//colorway market---------------------------------------
let marketArray = [];
colorway.markets.map((market)
=> {
marketArray.push(market.marketCode);
});
colIndex
++;
newrow[colIndex]
= marketArray ? marketArray.join('/') : '';


workSheet.addRow(newrow).commit();

//setting row style
// let row = workSheet.lastRow;
// row.height = 120;

rowIndex
++;
});
});


//need retry array
let all_needProcessCellArray = [];
let firsttime_faild_cellArray
= [];
let secendtime_faild_cellArray
= [];

//define add image function
let fetchImageFun = function (workSheet, cell, CellArray) {
return new Promise((resolve, reject) => {
if (!cell.value) resolve('no');

// let starttime = new Date();
request.get({ url: cell.value, encoding: null, timeout: 10000 }, function (error, response, body) {
if (error) {
// let endtime = new Date();
// console.log(cell.address + ' Faild ' + starttime + ' ' + endtime);

if (CellArray) CellArray.push(cell);
resolve(
'err');
}

if (body) {
if (response.statusCode === 500) {
console.log(
'load image error from url:' + cell.value);
}
else if (response.statusCode === 404) {
console.log(
'can not load image from url:' + cell.value);
}
//get image
let imageObject = workBook.addImage({
buffer:
new Buffer(body),
extension: response.headers[
"content-type"]
});

//add image to cell
let imageCellName = cell.address + ':' + cell.address;
workSheet.addImage(imageObject, imageCellName);

//clear value
cell.value = '';

resolve(
'ok');
}
});
});
}


let functionArray
= [];
//add image to cell
workSheet.eachRow({ includeEmpty: true }, function (row, rowNumber) {
if (rowNumber > 1) {
row.height
= 150;

row.eachCell({ includeEmpty:
true }, function (cell, colNumber) {

cell.alignment
= { vertical: 'top', horizontal: 'left' };

// cell.border = {
// top: { style: 'thin', color: { argb: 'FFFFFF00' } },
// left: { style: 'thin', color: { argb: 'FFFFFF00' } },
// bottom: { style: 'thin', color: { argb: 'FFFFFF00' } },
// right: { style: 'thin', color: { argb: 'FFFFFF00' } }
// };

//add image is work
if (colNumber === 2 || colNumber === 3) {
all_needProcessCellArray.push(cell);
}
});
}
});


all_needProcessCellArray.forEach((getCell)
=> {
functionArray.push(fetchImageFun(workSheet, getCell, firsttime_faild_cellArray));
});
//add function to array

//resolve function
Promise.all(functionArray)
.then((result)
=> {

if (firsttime_faild_cellArray) {
firsttime_faild_cellArray.forEach((getCell)
=> {
functionArray.push(fetchImageFun(workSheet, getCell, secendtime_faild_cellArray));
});
//first time retry
Promise.all(functionArray)
.then((result2)
=> {

if (secendtime_faild_cellArray) {
secendtime_faild_cellArray.forEach((getCell)
=> {
functionArray.push(fetchImageFun(workSheet, getCell));
});
//secend time retry
Promise.all(functionArray)
.then((result2)
=> {
resolve(workBook);
}).
catch((err3) => {
reject(
null);
});
}
else {
resolve(workBook);
}

}).
catch((err2) => {
reject(
null);
});
}
else {
resolve(workBook);
}

}).
catch((err) => {
reject(
null);
})
});
}
View Code

API路由代码

let express = require('express');
let genCSV
= require("./genCSV.js");
let exceljs
= require('exceljs');
let util
= require('util');
let fs
= require('fs');

let router
= express.Router();

//post data to router
router.post('/', function (req, res, next) {
genCSV.getLinePlanExcelJson(req.body)
.then((excelObject)
=> {


// throw new Error('this is test error');

//return to client
let fileName = 'LinePlan-' + req.body.linePlanID + '.xlsx';
let filePath
= './public/temp/' + fileName;
if (fs.existsSync(filePath)) {
fs.unlink(filePath);
}

excelObject.xlsx.writeFile(filePath, { bookType:
'xlsx', bookSST: false, type: 'buffer' })
.then(()
=> {
res.status(
200).download(filePath, fileName);
}).
catch((err) => {
throw err
});

})
.
catch((err) => {
res.status(
500).end('{"err":"' + err.message + '"}');
});
});

module.exports
= router;
View Code

 

 

前台Client调用代码

    fetchMethodExcel: function (apiName, method, requestObject, requestBody, callback) {
fetch3(
this.apiExport(apiName, requestObject), {
// method: method,
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody),
})
.then((data)
=> {
if (data.status === 500) {
throw new Error('Explort LinePlan API Error');
}
else if (data.status === 404) {
throw new Error('Can Not Found Explort LinePlan API');
}
return data.blob();
})
.then((blob)
=> {
let a
= document.createElement('a');
let url
= window.URL.createObjectURL(blob);

let filename
= 'LinePlan-' + requestBody.linePlanID + '.xlsx';
a.href
= url;
a.download
= filename;
a.click();
window.URL.revokeObjectURL(url);

callback();
})
.
catch(err => {
callback(err);
});
}
View Code

 

运行结果是

但是下载的文件却是无法打开的,一直说是文件有内容有问题,尝试恢复很久都没有返回。

解除锁定后,可以正常打开文件了

 


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • uniapp开发H5解决跨域问题的两种代理方法
    本文介绍了uniapp开发H5解决跨域问题的两种代理方法,分别是在manifest.json文件和vue.config.js文件中设置代理。通过设置代理根域名和配置路径别名,可以实现H5页面的跨域访问。同时还介绍了如何开启内网穿透,让外网的人可以访问到本地调试的H5页面。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • express工程中的json调用方法
    本文介绍了在express工程中如何调用json数据,包括建立app.js文件、创建数据接口以及获取全部数据和typeid为1的数据的方法。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 图片复制到服务器 方向变了_双服务器热备更新配置文件步骤问题及解决方法
    本文介绍了在将图片复制到服务器并进行方向变换的过程中,双服务器热备更新配置文件所出现的问题及解决方法。通过停止所有服务、更新配置、重启服务等操作,可以避免数据中断和操作不规范导致的问题。同时还提到了注意事项,如Avimet版本的差异以及配置文件和批处理文件的存放路径等。通过严格执行切换步骤,可以成功进行更新操作。 ... [详细]
  • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
author-avatar
mobiledu2502869223
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有