jung-kurt / gofpdf

A PDF document generator with high level support for text, drawing and images
http://godoc.org/github.com/jung-kurt/gofpdf
MIT License
4.29k stars 772 forks source link

Sent to frontend issue #315

Closed kolkov closed 4 years ago

kolkov commented 4 years ago

If I save pdf file localy I se Hellow world! But if I send it to frontend I see only a blank page. :(

pdf := createInvoice()
    c.Response.Header().Set("Content-Type", "application/pdf")
    var b bytes.Buffer
    err = pdf.Output(&b)
    if err != nil {
        return err
    }
    pdf.Close()
    bytesPdf := b.Bytes()
    return c.Write(bytesPdf)
func createInvoice() *gofpdf.Fpdf {
    pdf := gofpdf.New("P", "mm", "A4", "")
    pdf.AddPage()
    pdf.SetFont("Arial", "B", 16)
    pdf.Cell(40, 10, "Hello, world!")
    pdf.Cell(40, 10, "Привет, мир!")
    //_ = pdf.OutputFileAndClose("hello.pdf")
    return pdf
}

local

%PDF-1.3
3 0 obj
<</Type /Page
/Parent 1 0 R
/Resources 2 0 R
/Contents 4 0 R>>
endobj
4 0 obj
<</Filter /FlateDecode /Length 162>>
stream
xLÌ1
Â0Åñ=§xÝ,”ø%M³
UqΪI„R(¸t-^Ä;B‘ÞHªNoù½?áÈ-#^Œ8aÿÛÛ:¬w±òÒ‡*–ÚÚ&¨“ô›R´ôdƒŽg%¤†Ðœ.¢v˳\X«–¶óXB×õ†þÚù,w-¾N¨øƒé>iJôœoÒ+Mó˜å®EíØ;

remote

%PDF-1.3
3 0 obj
<</Type /Page
/Parent 1 0 R
/Resources 2 0 R
/Contents 4 0 R>>
endobj
4 0 obj
<</Filter /FlateDecode /Length 162>>
stream
xLÌ1
Â0Åñ=§xÝ,”ø%M³
UqΪI„R(¸t-^Ä;B‘ÞHªNoù½?áÈ-#^Œ8aÿÛÛ:¬w±ò҇*–ÚÚ&¨“ô›R´ôdƒŽg%¤†Ðœ.¢v˳\X«–¶óXB×õ†þÚù,w-¾N¨øƒé>iJôœoÒ+Mó˜å®EíØ;
jung-kurt commented 4 years ago

Assuming c.Response is an http.ResponseWriter, then something like this (untested) should work:

c.Response.Header().Set("Content-Type", "application/pdf")
pdf.Output(c.Response)
pdf.Close()

If you want to buffer the PDF document to check for errors, then you can call b.WriteTo(c.Response) and skip the generation of a byte slice. If you do use a byte slice, then I think you want c.Response.Write(bytesPdf) rather than c.Write(bytesPdf).

kolkov commented 4 years ago

ozzo handlers should return an error https://github.com/go-ozzo/ozzo-routing#handlers

kolkov commented 4 years ago
pdf := createInvoice()
    c.Response.Header().Set("Content-Type", "application/pdf")
    //var b bytes.Buffer
    err = pdf.Output(c.Response)
    //if err != nil {
    //  return err
    //}
    pdf.Close()
    //bytesPdf := b.Bytes()
    return err

yes this worked, but I still get empty page without any text, but now file content instead base64 string.

kolkov commented 4 years ago

And how to use utf-8 cyrillic text?

jung-kurt commented 4 years ago

go.mod

module issue_315

go 1.13

require github.com/jung-kurt/gofpdf/v2 v2.13.4

go.sum

github.com/jung-kurt/gofpdf/v2 v2.13.4 h1:YuHpTFh1Sl1p3PxeZzcSIQbxSSMpjd/f/ICU7xyhp7E=
github.com/jung-kurt/gofpdf/v2 v2.13.4/go.mod h1:RF/RGAP0AS4rd9fVZ6gb7Lbw6178P/AdAxMRW8Kn/Vk=

issue_315.go

package main

import (
  "bytes"
  "fmt"
  "io"
  "net/http"
  "os"

  "github.com/jung-kurt/gofpdf/v2"
)

func generateDoc(w io.Writer) (err error) {
  pdf := gofpdf.New("P", "mm", "A4", "")
  pdf.AddPage()
  pdf.AddUTF8Font("dejavu", "", "../gofpdf/font/DejaVuSansCondensed.ttf")
  pdf.SetFont("dejavu", "", 12)
  pdf.Cell(40, 10, "Привет, мир!")
  err = pdf.Output(w)
  pdf.Close()
  return
}

func serve(w http.ResponseWriter, r *http.Request) {
  var err error
  var buf bytes.Buffer
  err = generateDoc(&buf)
  if err == nil {
    w.Header().Set("Content-Type", "application/pdf")
    buf.WriteTo(w)
  } else {
    w.WriteHeader(http.StatusInternalServerError)
  }
  return
}

func main() {
  const addrStr = "127.0.0.1:8080"
  http.HandleFunc("/", serve)
  fmt.Printf("listening on %s\n", addrStr)
  err := http.ListenAndServe(addrStr, nil)
  if err != nil {
    fmt.Fprintf(os.Stderr, "%s\n", err.Error())
  }
}