使用Golang创建包含西里尔字母的PDF。

huangapple go评论76阅读模式
英文:

golang create pdf with cyrillic

问题

我需要在Go语言中创建包含西里尔字母的PDF文件。我已经尝试了https://github.com/jung-kurt/gofpdf,但它需要1251编码的字符才能正确显示西里尔字母。

然后我尝试使用https://github.com/golang/freetype创建带有文本的图像,然后将其插入到PDF中。所以我尝试了以下代码:

package main

import (
    "github.com/jung-kurt/gofpdf"
    "github.com/golang/freetype"
    "image"
    "fmt"
    "os"
    "bytes"
    "image/jpeg"
    "io/ioutil"
    "image/draw"
)

func main() {
    pwd, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    dataFont, err := ioutil.ReadFile(pwd + "/font/luxisr.ttf")
    if err != nil {
        fmt.Printf("%v",err)
    }
    f, err := freetype.ParseFont(dataFont)
    if err != nil {
        fmt.Printf("%v",err)
    }
    dst := image.NewRGBA(image.Rect(0, 0, 800, 600))
    draw.Draw(dst, dst.Bounds(), image.White, image.ZP, draw.Src)
    c := freetype.NewContext()
    c.SetDst(dst)
    c.SetClip(dst.Bounds())
    c.SetSrc(image.Black)
    c.SetFont(f)
    c.DrawString("русский текст", freetype.Pt(0, 16))
    pdf := gofpdf.New("P", "mm", "A4", "")
    pdf.AddPage()
    buf := new(bytes.Buffer)
    err = jpeg.Encode(buf, dst, nil)

    if err != nil {
        fmt.Printf("%v",err)
    }

    reader := bytes.NewReader(buf.Bytes())
    textName := "text1"
    pdf.RegisterImageReader(textName, "jpg", reader)
    pdf.Image(textName, 15, 15, 0, 0, false, "jpg", 0, "")
    pdf.OutputFileAndClose("test.pdf")
}

但结果是我收到了方块而不是文本,因为似乎freetype需要使用Unicode符号来显示文本。

是否可以将通常以UTF-8编码的字符串转换为Unicode?我该如何创建包含西里尔文本的PDF或图像?

谢谢。

英文:

I need to create pdf file in go with cyrillic symbols. I've started with https://github.com/jung-kurt/gofpdf but it needs 1251 symbols to produce correct cyrillic.
I've tried

package main
import (
"github.com/jung-kurt/gofpdf"
"fmt"
"os"
)
func main() {
pwd, err := os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddFont("Helvetica", "", pwd + "/font/helvetica_1251.json")
pdf.AddPage()
pdf.SetFont("Helvetica", "", 16)
tr := pdf.UnicodeTranslatorFromDescriptor("cp1251")
pdf.Cell(15, 50, tr("русский текст"))
pdf.OutputFileAndClose("test.pdf")
}

but it produce only dots instead of text.

Then I've tried to use https://github.com/golang/freetype to create image with text and then insert it to pdf. So I've tried

package main
import (
"github.com/jung-kurt/gofpdf"
"github.com/golang/freetype"
"image"
"fmt"
"os"
"bytes"
"image/jpeg"
"io/ioutil"
"image/draw"
)
func main() {
pwd, err := os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
dataFont, err := ioutil.ReadFile(pwd + "/font/luxisr.ttf")
if err != nil {
fmt.Printf("%v",err)
}
f, err := freetype.ParseFont(dataFont)
if err != nil {
fmt.Printf("%v",err)
}
dst := image.NewRGBA(image.Rect(0, 0, 800, 600))
draw.Draw(dst, dst.Bounds(), image.White, image.ZP, draw.Src)
c := freetype.NewContext()
c.SetDst(dst)
c.SetClip(dst.Bounds())
c.SetSrc(image.Black)
c.SetFont(f)
c.DrawString("русский текст", freetype.Pt(0, 16))
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddPage()
buf := new(bytes.Buffer)
err = jpeg.Encode(buf, dst, nil)
if err != nil {
fmt.Printf("%v",err)
}
reader := bytes.NewReader(buf.Bytes())
textName := "text1"
pdf.RegisterImageReader(textName, "jpg", reader)
pdf.Image(textName, 15, 15, 0, 0, false, "jpg", 0, "")
pdf.OutputFileAndClose("test.pdf")
}

but as a result I receive squares instead of text because it seems that freetype needs unicode symbols for text.

Is it possible to convert strings which are generally in utf-8 to unicode? How can I create pdf or image with cyrillic text?

Thank you.

答案1

得分: 2

首先,你忽略了最后一行的错误。pdf.OutputFileAndClose 返回一个错误,所以你应该检查它:

err := pdf.OutputFileAndClose("test.pdf")
if err != nil {
    log.Fatal(err)
}

除此之外,你的第一个示例对我来说是有效的。生成的输出如下所示:

使用Golang创建包含西里尔字母的PDF。

以下是我使用的代码,你会发现它与你的代码非常相似:

package main

import (
    "log"

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

func main() {
    pdf := gofpdf.New("P", "mm", "A4", "")
    pdf.AddFont("Helvetica", "", "helvetica_1251.json")
    pdf.AddPage()
    pdf.SetFont("Helvetica", "", 16)
    tr := pdf.UnicodeTranslatorFromDescriptor("cp1251")
    pdf.Cell(15, 50, tr("русский текст"))
    err := pdf.OutputFileAndClose("test.pdf")
    if err != nil {
        log.Println(err)
    }
}

使用上述代码时,重要的是确保 helvetica_1251.zhelvetica_1251.jsoncp1251.map(来自 $GOPATH/src/github.com/jung-kurt/gofpdf/font,或者由 makefont 工具生成)都在当前目录中。如果你确认这对你有效,你可以将它们移动到字体目录并相应地更改代码。我猜测你可能在默默地忽略一个关于这些文件之一的错误警告。

附注:我正在运行 Mac OS X。如果你使用的是其他系统,请确保安装了支持 Cyrillic 字符的 Helvetica 版本。

更新

对于将来遇到这个问题的其他人,我想在这里添加最终的解决方案。来自下面的评论:

感谢 jung-kurt,我找到了解决方案。你可以通过添加 pdf.SetCompression(true) 来避免在 Windows 上出现此错误 - Timur Shahmuratov

英文:

First, you are ignoring an error in the final line. pdf.OutputFileAndClose returns an error, so you should check it:

err := pdf.OutputFileAndClose("test.pdf")
if err != nil {
log.Fatal(err)
}

Other than that, your first example works for me. The generated output looks like this:

使用Golang创建包含西里尔字母的PDF。

Here is the code I used, you'll see it's very similar to yours:

package main
import (
"log"
"github.com/jung-kurt/gofpdf"
)
func main() {
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddFont("Helvetica", "", "helvetica_1251.json")
pdf.AddPage()
pdf.SetFont("Helvetica", "", 16)
tr := pdf.UnicodeTranslatorFromDescriptor("cp1251")
pdf.Cell(15, 50, tr("русский текст"))
err := pdf.OutputFileAndClose("test.pdf")
if err != nil {
log.Println(err)
}
}

With the above code, the important thing is to make sure helvetica_1251.z, helvetica_1251.json and cp1251.map (from $GOPATH/src/github.com/jung-kurt/gofpdf/font, or generated by the makefont tool) are all in the current directory. If you can confirm that this works for you, you can proceed to move them into the fonts directory and changing the code accordingly. My best guess is that you may be silently ignoring an error warning you about one of these files.

PS I'm running Mac OS X. If you are on another system, make sure you have a version of Helvetica with cyrillic character support installed.

Update

For others facing this problem in the future, I wanted to add the final solution here. From the comments below:

> Thanks to jung-kurt I found solution. You can avoid this bug on Windows by adding pdf.SetCompression(true) – Timur Shahmuratov

huangapple
  • 本文由 发表于 2016年2月10日 14:25:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/35308271.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定