我不是一位经验丰富的 Go 开发人员,我通常为工作任务自动化做一些小型微服务。所以我有一个任务来更新现有的 PDF 文件,添加 QR 码和旁边的一些注释。文件和评论将来自 HTML 表单(不,我使用 Postman 进行测试)。这花了我一些时间,但最后我弄清楚如何获取文件和字符串,生成街机,将其插入 pdf 并保存。在这里我遇到了一个问题,每次将文件保存为 pdf 时,页面分辨率都会增加一倍。我在调试期间查看页面大小参数,直到函数结束时,保存它等于导入文件中的原始大小,然后保存,它加倍。
因此,如果您尝试将 QR 添加到生成的文件中,则 if 会更小,下次甚至更小,并且它会以这种方式表现,直到无穷大。我需要能够逐步(由不同的人)将多个二维码添加到具有相同格式的同一文件中。
我尝试使用固定页面大小,但没有帮助,尝试添加页面而不格式化它会生成非常奇怪的事情。
我使用 go 版本 1.20.2 来处理我使用的 PDF
"github.com/phpdave11/gofpdf"
"github.com/phpdave11/gofpdf/contrib/gofpdi"
您可以在下面找到代码本身
// Handling of post requests in order update pdf file
func (a *App) qrAddToFile(w http.ResponseWriter, r *http.Request) {
var png []byte //byte array for qrcode in png
// here we get data from form whic is string for qr generation and pdf file where this qr need to be inserted
r.ParseMultipartForm(4048)
qrstring := r.FormValue("qrstring")
png, err := qrcode.Encode(qrstring, qrcode.Medium, 256) //decode string into qr png image
pngfile := savePngToFile(png) //save image to file
file, fileHeader, err := r.FormFile("qrfile") //get pdf file from post request
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
// Save pdf file under unique name
tmpfilename := fmt.Sprintf("./%d%s", time.Now().UnixNano(), fileHeader.Filename)
dst, err := os.Create(tmpfilename)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer dst.Close()
_, err = io.Copy(dst, file)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// start import pdf as a template
imp := gofpdi.NewImporter()
pdf := gofpdf.New("P", "mm", "A4", "")
rs, _ := getTemplatePdf(tmpfilename)
tpl := imp.ImportPageFromStream(pdf, &rs, 1, "/MediaBox")
pageSizes := imp.GetPageSizes()
nrPages := len(imp.GetPageSizes())
var sizeType gofpdf.SizeType
for i := 1; i <= nrPages; i++ {
tpl = imp.ImportPageFromStream(pdf, &rs, i, "/MediaBox")
sizeType.Wd = pageSizes[i]["/MediaBox"]["w"]
sizeType.Ht = pageSizes[i]["/MediaBox"]["h"]
pdf.AddPageFormat("P", sizeType)
imp.UseImportedTemplate(pdf, tpl, 0, 0, sizeType.Wd, sizeType.Ht)
}
// import all pages from exsisting file
pdf.AddPageFormat("P", sizeType) // add new page same format as previous
// add qrcode on page
rdr := bytes.NewReader(png)
_ = pdf.RegisterImageOptionsReader(pngfile, gofpdf.ImageOptions{ImageType: "png", ReadDpi: true}, rdr)
pdf.Image(pngfile, 10, pdf.GetY()+5, 200, 200, false, "", 0, "")
// add some comments on left side of qr code
tr := pdf.UnicodeTranslatorFromDescriptor("cp1251")
pdf.AddFont("Helvetica", "", "helvetica_1251.json")
pdf.SetFont("Helvetica", "", 27)
pdf.SetXY(220, 10)
pdf.SetCellMargin(2)
pdf.MultiCell(370, 12, tr(qrstring), "1", "", false)
err = pdf.Error()
checkErr(err)
err = pdf.OutputFileAndClose("QR.pdf") // save file
checkErr(err)
}
func getTemplatePdf(fname string) (io.ReadSeeker, error) {
file, err := os.Open(fname) // For read access.
if err != nil {
log.Fatal(err)
}
readSeek := io.ReadSeeker(file)
return readSeek, nil
}
我陷入了困境,有人可以帮助我吗?
致以诚挚的问候 阿图尔
抱歉,我找到了问题的根源,都是关于单位的。在我的代码中是
pdf := gofpdf.New("P", "mm", "A4", "")
我需要做的一切将其更改为
pdf := gofpdf.New("P", "pt", "A4", "")
一切都运行得很完美。