使用GoLang mgo在MongoDb中保存pdf

问题描述:

我阅读了多篇关于使用mgo保存文件的博客,但无法找到针对以下特定需求的解决方案,请大声喊出!使用GoLang mgo在MongoDb中保存pdf

下面插入对象的MongoDB:

var dbSchoolPojo dbSchool 
i := bson.NewObjectId() 
dbSchoolPojo.ID = i 
coll := db.C("school") 
coll.Insert(&dbSchoolPojo) 

下面能够得到文件的保留:现在

file, handler, err := r.FormFile("pdf") //Able to get file from r *http.Request 

,插入对象之前,我需要设置像上面这样的文件:

dbSchoolPojo.pdf = file.Bytes(); //Of course Bytes() is invalid method 

我的结构对象:

type dbSchool struct { 
    ID bson.ObjectId `json:"id" bson:"_id,omitempty"` 
    ... 
    Pdf []byte `json:"pdf" bson:"pdf"` 
    ... 
} 

通俗地说,问题是:如何通过使用mgo驱动程序的GoLang结构在mongoDb中插入文件(从HTML表单接收)?

感谢您的阅读! :)


更新:

PDF存储在MongoDB中象下面这样:

Binary('EWHKDSH876KJHlkjdswsddsfsd3232432njnjkn2dljDSFSDFIJSFD333...') 

下面的代码工作没有错误,但不提供PDF文件:

func DownloadPdf(w http.ResponseWriter, r *http.Request, db mongoDB) { 
    var school dbSchool 
    coll := db.C("schools") 

    incomingId = "59e6404e2f68182a74610f19"; //This mongo DB _id is received from GET URL request 

    err := coll.Find(bson.M{"_id": bson.ObjectIdHex(incomingId)}). 
     Select(bson.M{"pdf": 1}).One(&school) 
    if err != nil { 
     serve404(w, r, db) 
     return 
    } 

    buffer := school.Pdf 
    w.Header().Set("Content-Disposition", "attachment; filename=abc.pdf") 
    w.Header().Set("Content-Type", "application/pdf") 
    w.Header().Set("Content-Length", strconv.Itoa(len(buffer))) 

    if _, err := w.Write(buffer); err != nil { 
     log.Println("unable to serve image.") //This line is not executed 
    } 
} 

JQuery co德来请求内容:

 $(".downloadPdfFile").click(function() { 
      var domain = document.location.origin; 
      window.open(domain+'/brochure/59e6404e2f68182a74610f19', '_blank'); 
     }); 

file通过Request.FormFile()返回是multipart.File类型,是的:

type File interface { 
    io.Reader 
    io.ReaderAt 
    io.Seeker 
    io.Closer 
} 

它实现io.Reader,所以你可以简单地读取例如其内容与ioutil.ReadAll()

data, err := io.ReadAll(file) 
// Handle error 

然后:

dbSchoolPojo.Pdfdata = data 

但存储大文件,文件的一部分是不是最佳/有效。请转到MongoDB GridFS,这也支持mgoDatabase.GridFS()

这里是你如何存储在MongoDB中GridFS的文件(例如,从GridFS.Create()拍摄):

func check(err error) { 
    if err != nil { 
     panic(err.String()) 
    } 
} 
file, err := db.GridFS("fs").Create("myfile.txt") 
check(err) 
n, err := file.Write([]byte("Hello world!")) 
check(err) 
err = file.Close() 
check(err) 
fmt.Printf("%d bytes written\n", n) 

使用GridFS,你也可以保存文件,而无需先阅读所有内容到内存中,如果你将文件内容“流”到mgo.GridFile,因为它实现io.Writer。呼叫io.Copy()

// ... 
file, handler, err := r.FormFile("pdfFile") 

// ... 
mongoFile, err := db.GridFS("fs").Create("somepdf.pdf") 
check(err) 

// Now stream from HTTP request into the mongo file: 
written, err := io.Copy(mongoFile, file) 
// Handle err 

err = mongoFile.Close() 
check(err) 

编辑:更新回答您的更新

当你所服务的PDF,您查询的文档中的错误的方式:

err := coll.Find(bson.M{"_id": bson.ObjectIdHex(incomingId)}). 
    Select(bson.M{"pdf": 1}).One(&school) 

您选择pdf场检索,但你在MongoDB中的文档没有这样的字段:

type dbSchool struct { 
    ID bson.ObjectId `json:"id" bson:"_id,omitempty"` 
    ... 
    Pdfdata []byte `json:"pdf"` 
    ... 
} 

此类型定义将导致pdfdata字段,但不是pdf。添加适当的mgo结构标签:

type dbSchool struct { 
    ID bson.ObjectId `json:"id" bson:"_id,omitempty"` 
    ... 
    Pdfdata []byte `json:"pdf" bson:"pdf"` 
    ... 
} 

或选定字段更改从pdfpdfdata

+0

你好@icza,它的工作!还有一个问题:现在我在struct object中获取字节数据,下一步是将这些数据转换为pdf文件并允许用户通过网络浏览器下载。你能帮忙吗? –

+0

@NikhilJoshi为了开始检查这个问题:[PDF下载不是从goat中的serverside工作](https://*.com/questions/41238407/pdf-download-is-not-working-from-serverside-in- golang)。 – icza

+0

你好@icza,我试过了,但它不能完全工作。请参阅原文中的UPDATE。 –