使用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,这也支持mgo
:Database.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"`
...
}
或选定字段更改从pdf
到pdfdata
。
你好@icza,它的工作!还有一个问题:现在我在struct object中获取字节数据,下一步是将这些数据转换为pdf文件并允许用户通过网络浏览器下载。你能帮忙吗? –
@NikhilJoshi为了开始检查这个问题:[PDF下载不是从goat中的serverside工作](https://*.com/questions/41238407/pdf-download-is-not-working-from-serverside-in- golang)。 – icza
你好@icza,我试过了,但它不能完全工作。请参阅原文中的UPDATE。 –