使用Golang创建带有西里尔字母的PDF。

3

我需要使用Go语言创建带有西里尔字母的PDF文件。我已经开始使用https://github.com/jung-kurt/gofpdf,但需要1251个符号才能正确生成西里尔字母。我已经尝试过

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")
}

但它只生成了点而不是文本。
然后我尝试使用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或图像?
谢谢。

UTF-8是Unicode的一种编码方式。具体来说,它是Unicode的一种无损8位编码。所以这不是你的问题。 - Linear
1个回答

2

首先,您忽略了最后一行中的错误。 pdf.OutputFileAndClose 返回一个错误,因此您应该检查它:

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

除此之外,你的第一个例子对我有用。生成的输出如下:

PDF Output

这是我使用的代码,你会发现它和你的非常相似:

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工具生成)都在当前目录中。如果您确认这对您有效,可以继续将它们移动到字体目录并相应地更改代码。我最好的猜测是您可能会无声地忽略一个有关这些文件之一的错误警告。
PS 我正在运行Mac OS X。如果您使用的是其他系统,请确保安装了支持西里尔字符的Helvetica版本。
更新
对于未来遇到此问题的其他人,我想在此添加最终解决方案。来自下面的评论:
感谢jung-kurt,我找到了解决方案。您可以通过添加pdf.SetCompression(true)来避免Windows上的此错误 - Timur Shahmuratov

谢谢回复。我使用的是来自 https://github.com/jung-kurt/gofpdf/tree/master/font 的字体,并将其复制到项目目录中。json 映射也来自该处。在 pdf.OutputFileAndClose 上没有收到任何错误提示。这可能是因为字体位于单独的“font”文件夹中吗? - Timur Shahmuratov
@TimurShahmuratov 嗯,那我不知道了。可能你需要在系统上安装字体吗?我不确定PDF是生成失败还是你的系统无法正确显示它。你在Windows 10上可能没有 Helvetica 字体。另一件事是,你可以尝试使用 makefont 工具制作一个支持 Cyrillic 文本的字体,然后使用生成的文件运行代码。除此之外,很抱歉我没有其他想法! - Herman Schaaf
1
已在Mac OSX上测试了代码。是的,它可以使用与Windows相同的字体工作。生成的PDF文件不同。已报告问题https://github.com/jung-kurt/gofpdf/issues/64。 - Timur Shahmuratov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接