Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何在NodeJS中的MongoDB中保存和检索pdf文件_Node.js_Mongodb_Pdfmake - Fatal编程技术网

Node.js 如何在NodeJS中的MongoDB中保存和检索pdf文件

Node.js 如何在NodeJS中的MongoDB中保存和检索pdf文件,node.js,mongodb,pdfmake,Node.js,Mongodb,Pdfmake,我遇到了一个问题,我在Node.js服务器后端使用Express将一个小pdf文件(~128KB)保存到Mongodb中的文档中。我没有使用Mongo GridFS,因为文件总是在16MB的限制之下。集合具有以下架构: const mongoose = require('mongoose'); const Schema = mongoose.Schema; const ReportsSchema = new Schema({ ReportFileData: Buffer, Cert_o

我遇到了一个问题,我在Node.js服务器后端使用Express将一个小pdf文件(~128KB)保存到Mongodb中的文档中。我没有使用Mongo GridFS,因为文件总是在16MB的限制之下。集合具有以下架构:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const ReportsSchema = new Schema({
  ReportFileData: Buffer,
  Cert_objid: { type: Schema.Types.ObjectId, ref: 'Certs' },
  Report_Type: String,
  Note: String,
  Dau_objID: { type: Schema.Types.ObjectId, ref: 'Dau' },
  Pau_objID: { type: Schema.Types.ObjectId, ref: 'Pau' }
});

module.exports = Reports = mongoose.model('Reports', ReportsSchema);
我使用以下代码创建pdf文件并保存它。我没有包括docDefinition,因为如果直接保存到服务器,它会生成正确的文件

const PdfPrinter = require('pdfmake/src/printer');
const path = require('path');
const moment = require('moment');

const Reports = require('../../models/Reports');  // Mongoose Schema

const createFAReport = data => {
    docDefinition...

createPdfBinary(docDefinition, binary => {
  const rpt = new Reports({
    ReportFileData: binary,
    Cert_objid: data._id,
    Report_Type: 'Water Use Report',
    Note: 'Testing 123'
  });

  rpt.save(err => {
    if (err) throw err;
    });
});

const createPdfBinary = (pdfDoc, callback) => {
  const fonts = {
    Roboto: {
    normal: path.join(__dirname, '../../', '/fonts/Roboto-Regular.ttf'),
    bold: path.join(__dirname, '../../', '/fonts/Roboto-Medium.ttf'),
    italics: path.join(__dirname, '../../', '/fonts/Roboto-Italic.ttf'),
    bolditalics: path.join(__dirname, '../../', '/fonts/Roboto-MediumItalic.ttf')
    }
  };

  const printer = new PdfPrinter(fonts);
  const doc = printer.createPdfKitDocument(pdfDoc);
  const chunks = [];
  let result;

  doc.on('data', function(chunk) {
    chunks.push(chunk);
  });
  doc.on('end', function() {
    result = Buffer.concat(chunks);
    callback('data:application/pdf;base64,' + result.toString('base64'));
  });
  doc.end();
};
然后,为了从MongoDB检索编码文档并将其写入本地文件进行测试,我使用了以下代码(请注意,聚合是为了获取检索正确报告所需的一些相关字段):

router.get('/getReport',passport.authenticate('jwt',{session:false}),(req,res)=>{
证书聚合([
{
$match:{
证书ID:'1578'
}
},
{
$lookup:{
来自:"报告",,
localField:“\u id”,
外国字段:“Cert_objid”,
as:‘rpt’
}
},
{
$REWIND:{
路径:“$rpt”,
IncludeArray索引:“”,
PreserveNullandEmptyArray:false
}
}
])。然后(结果=>{
result.map(rslt=>{
控制台日志(rslt.Cert\u ID);
res.json({msg:'Got the report.'});
const fullfilePath=path.join(uu dirname,“../”,“/public/pdffiles/”,`1578.pdf`
);
fs.writeFile(fullfilePath,rslt.rpt.ReportFileData,'base64',()=>{
log('文件已保存');
});
});
});
});

一切似乎都很好,除了当我打开文件时,我得到一个错误,文件已损坏。我想知道是否将其保存到“base64”是一个问题,或者MongoDB的数据类型是一个问题。数据类型为buffer,因此您是否将其作为缓冲区检索?任何帮助都将不胜感激。

我不建议将PDF或图像直接写入数据库。下面是一些关于原因的信息

您通常会保存一个文件名并将文件存储在一个文件系统中,您自己的或更具可扩展性的选项可能类似于S3


这是一个可能对您有所帮助的模块,如果您计划自己滚动,您仍然可以从中获得一些灵感。

保存pdf文件的名称,然后从MongoDB检索它。您应该为ex.:“uploads/docs”设置一个文件夹,然后在保存名为ex:“DOC1.pdf”的pdf文件时,将该文件写入“uploads/docs/DOC1.pdf”,并将文件名保存在MongoDB中。我希望我说得够清楚。不幸的是,我不理解你的评论。在Node.JS函数中创建pdf文件后,我希望将其保存到MongoDB,而不是本地文件。后来,我的最终目标是让它能够对屏幕上的显示做出反应,但在此之前,我一直在尝试将其从数据库输出到本地服务器副本进行测试。@Heath,Diamant说您应该只在数据库中存储名称。实际上不要将文件存储在那里。这是一种相当普遍的做法。您可以在mongo中存储名称或相对路径,然后将实际文件放在本地计算机上,或者使用AWS S3作为更具可扩展性的解决方案。除非你打算将这些数据流化,否则你最好还是按照惯例使用这些数据。@unfollors谢谢你的解释,这正是我想说的。多亏了你们,我明白了,我在以前的项目中也这样做过,但考虑到文档的大小和方便性,我想尝试直接保存到数据库的替代方法。感谢您提供的附加信息,这非常有用!mongodb本机支持上传文件,无需使用任何第三方anymore@SheeceGardazi这是正确的。MongoDB本机支持存储非常大的文件,包括PDF:
router.get('/getReport', passport.authenticate('jwt', { session: false }), (req, res) => {
  Certs.aggregate([
    {
      $match: {
        Cert_ID: '1578'
      }
    },
    {
      $lookup: {
        from: 'reports',
        localField: '_id',
        foreignField: 'Cert_objid',
        as: 'rpt'
      }
    },
    {
      $unwind: {
        path: '$rpt',
        includeArrayIndex: '<<string>>',
        preserveNullAndEmptyArrays: false
      }
    }
  ]).then(result => {
    result.map(rslt => {
      console.log(rslt.Cert_ID);
      res.json({ msg: 'Got the report.' });

      const fullfilePath = path.join(__dirname, '../../', '/public/pdffiles/', `1578.pdf`
      );

      fs.writeFile(fullfilePath, rslt.rpt.ReportFileData, 'base64', () => {
        console.log('File Saved.');
       });
     });
   });
 });