You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求比HPDF更简便的Haskell生成含UTF8文本PDF的方案

替代方案推荐

一、使用pdf-writer包(优先推荐)

这个包API设计简洁直观,原生支持完整UTF-8字符集,还能自动处理文本换行,无需手动拆分内容。

示例代码

{-# LANGUAGE OverloadedStrings #-}

module Main where

import qualified Data.ByteString.Lazy as LBS
import Graphics.PDF.Writer
import Graphics.PDF.Writer.Layout

main :: IO ()
main = do
  -- 定义带自动换行的文本内容,支持äöü、€等全UTF-8字符
  let content = layoutText def
        { layoutFont = Font "Helvetica" 12
        , layoutWidth = 580  -- 设置文本宽度阈值,超过自动换行
        } "测试文本:包含äöü和€符号,无需手动拆分换行,pdf-writer会自动处理排版。"
      -- 创建页面并添加内容
      page = pageWithContent def content
      -- 生成PDF文档结构
      doc = document def [page]
  -- 将文档写入文件
  LBS.writeFile "output.pdf" $ renderDocument doc

二、改进HPDF的现有使用方式

如果坚持使用HPDF,可以通过以下方法解决你遇到的两个问题:

  • 解决UTF-8字符不全问题:HPDF的标准字体(如Times_Roman)仅支持有限的拉丁字符,需加载支持完整UTF-8的TrueType字体(比如系统自带的DejaVu Sans、Arial Unicode MS等)。
  • 解决文本换行问题:自行实现简单的文本换行逻辑,或封装成复用函数。

改进后的HPDF示例代码

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Graphics.PDF
import qualified Data.Text as T

main :: IO ()
main = do
  let rect = PDFRect 0 0 600 400
  -- 加载系统中的TrueType字体(替换为你本地存在的字体路径)
  Right customFont <- mkFont "DejaVuSans.ttf"
  runPdf "improved_demo.pdf" (standardDocInfo { author="someone", compressed = False}) rect $ do
    page1 <- addPage Nothing
    drawWithPage page1 $ do
      -- 简单拆分文本为多行,可封装成通用换行函数
      let textLines = T.splitOn "\n" $ T.pack "测试文本:äöü 和 € 符号都能正常显示\n这是自动拆分的第二行内容"
          startY = 380
          lineHeight = 20
      mapM_ (\(i, line) -> drawText $ text (PDFFont customFont 12) 10 (startY - i*lineHeight) (T.unpack line)) (zip [0..] textLines)

其他可选包

  • cairo+pango:通过Cairo渲染PDF,Pango负责专业文本布局与全UTF-8支持,适合复杂排版场景,但依赖系统底层库。
  • hslua-pdf:基于Lua的PDF生成封装库,隐藏了底层细节,易用性较好,但需要Lua环境支持。

内容的提问来源于stack exchange,提问作者user855443

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:05:05