我正在处理使用https://github.com/DaftMonk/generator-angular-fullstack生成的meanjs
应用程序。我正在尝试使用phantomjs
生成.pdf文件并将其下载到浏览器。
问题是,无论页数如何,下载的.pdf文件始终显示空白页。服务器上的原始文件未损坏。当我进一步调查时,发现下载的文件总是远大于磁盘上的原始文件。此问题也只发生在.pdf文件中。其他文件类型工作正常。
我尝试了多种方法,例如res.redirect('http://localhost:9000/assets/exports/receipt.pdf');
,res.download('client\\assets\\exports\\receipt.pdf')
,
var fileSystem = require('fs');
var stat = fileSystem.statSync('client\\assets\\exports\\receipt.pdf');
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Length': stat.size
});
var readStream = fileSystem.createReadStream('client\\assets\\exports\\receipt.pdf');
return readStream.pipe(res);
甚至我已尝试使用https://github.com/expressjs/serve-static,但结果没有变化。
我是nodejs
的新手。将.pdf文件下载到浏览器的最佳方法是什么?
更新 我在Windows 8.1 64位计算机上运行它
答案 0 :(得分:4)
这是一种从express提供文件的简洁方法,并使用attachment
标头确保文件已下载:
var path = require('path');
var mime = require('mime');
app.get('/download', function(req, res){
//Here do whatever you need to get your file
var filename = path.basename(file);
var mimetype = mime.lookup(file);
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type', mimetype);
var filestream = fs.createReadStream(file);
filestream.pipe(res);
});
答案 1 :(得分:3)
通常如果您使用幻像生成pdf,那么该文件将被写入光盘,您必须提供路径和回放到渲染功能。
router.get('/pdf', function(req, res){
// phantom initialization and generation logic
// supposing you have the generation code above
page.render(filePath, function (err) {
var filename = 'myFile.pdf';
res.setHeader('Content-type', "application/pdf");
fs.readFile(filePath, function (err, data) {
// if the file was readed to buffer without errors you can delete it to save space
if (err) throw err;
fs.unlink(filePath);
// send the file contents
res.send(data);
});
});
});
答案 2 :(得分:3)
有几种方法可以做到这一点:
现在您可以使用浏览器中的URL直接打开文件,如:
window.open('http://localhost:9000/assets/exports/receipt.pdf');
或
res.redirect('http://localhost:9000/assets/exports/receipt.pdf');
应该有效。
第二种方式是读取文件,数据必须作为缓冲区。实际上,如果您直接发送它应该被识别,但您可以尝试使用以下命令将其转换为base64编码:
var base64String = buf.toString('base64');
然后设置内容类型:
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Length': stat.size
});
并将数据作为响应发送。 我将尝试举例说明这一点。
编辑:你甚至不需要编码。你可以尝试一下。但是我甚至没有编码就能使它工作。
另外,您也不需要设置标题。 Express为您服务。以下是为获取pdf而编写的API代码片段,以防它不是公共/静态的。您需要API来提供pdf:
router.get('/viz.pdf', function(req, res){
require('fs').readFile('viz.pdf', function(err, data){
res.send(data);
})
});
最后,请注意,获取pdf的URL具有扩展名pdf,这是供浏览器识别传入文件是pdf。否则它将保存文件而不进行任何扩展。
答案 3 :(得分:0)
我没有您所提到的框架的经验,但我建议使用像Fiddler这样的工具来查看正在发生的事情。例如,您可能不需要添加内容长度标头,因为您正在流式传输,并且您的框架会进行分块传输编码等。