寻求比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
相关产品推荐
相关产品推荐

