使用Puppeteer Sharp生成PDF时混合文本(希伯来语/英/数)排版异常
问题
在.NET Web API中使用Puppeteer Sharp(版本18.0.4)生成包含希伯来语、英语与数字混合产品名的PDF时,出现文本渲染异常:含希伯来语和数字的产品名字符顺序错乱。例如产品名"(100) 2024 Hebrewtext"本应正常显示,实际却显示为"100) 2024 Hebrewtext)"。相关核心代码如下:
[HttpGet()] public async Task<IActionResult> GeneratePdf() { try { var launchOptions = new LaunchOptions { Headless = true }; var browserFetcher = new BrowserFetcher(); await browserFetcher.DownloadAsync(); using var browser = await Puppeteer.LaunchAsync(launchOptions); using var page = await browser.NewPageAsync(); List<Product> products = new List<Product> { new Product { Id = 1, Name = "(100) 2024 Hebrewtext" }, }; var htmlTemplate = // 此处为HTML模板内容 string htmlContent = GenerateHtml(htmlTemplate, products); await page.SetContentAsync(htmlContent); var pdfOptions = new PdfOptions { Format = PuppeteerSharp.Media.PaperFormat.A4, PrintBackground = true }; var pdfStream = await page.PdfStreamAsync(pdfOptions); var fileName = "invoice.pdf"; var filePath = Path.Combine(@"C:", fileName); using (var fileStream = new FileStream(filePath, FileMode.Create)) { await pdfStream.CopyToAsync(fileStream); } return File(filePath, "application/pdf", fileName); } catch (Exception ex) { // 异常处理逻辑 } }
如何确保含希伯来语、英语、数字及特殊字符的产品名在生成的PDF中正确显示?
解决方案
1. 控制HTML文本方向与双向文本隔离
希伯来语是右到左(RTL)语言,混合左到右(LTR)内容时,浏览器双向文本算法易出现错乱,需通过HTML属性明确控制:
- 给包含混合文本的元素添加
dir="auto",让浏览器自动识别主导文本方向:
<span dir="auto">(100) 2024 Hebrewtext</span>
- 用
<bdi>标签隔离独立文本块,避免不同方向内容互相干扰:
<bdi dir="ltr">(100) 2024</bdi> <bdi dir="rtl">Hebrewtext</bdi>
2. 确保字体支持希伯来语字符
使用不支持希伯来语的字体会导致排版错乱,需配置兼容字体:
- 在HTML样式中引入支持希伯来语的字体,比如系统自带的
Arial Hebrew、Times New Roman Hebrew,或开源字体Noto Sans Hebrew:
.product-name { font-family: 'Arial Hebrew', 'Noto Sans Hebrew', sans-serif; }
- 确保服务器环境安装了对应字体,或在Puppeteer启动参数中指定字体路径,避免无头模式下字体缺失。
3. 调整Puppeteer PDF生成配置
优化PDF生成参数,确保文本排版规则生效:
- 在
PdfOptions中启用PreferCSSPageSize,让CSS中的文本方向设置优先:
var pdfOptions = new PdfOptions { Format = PuppeteerSharp.Media.PaperFormat.A4, PrintBackground = true, PreferCSSPageSize = true };
- 若存在字体替换问题,禁用自动字体替换:
var launchOptions = new LaunchOptions { Headless = true, Args = new[] { "--disable-font-substitution" } };
4. 用Unicode控制字符预处理文本
对含特殊符号的混合文本,添加Unicode双向控制字符强制方向:
- 在需要保持LTR顺序的文本前添加
\u200E(左到右标记),确保数字和特殊字符顺序正确:
// 预处理产品名称,修正括号与数字的顺序 product.Name = $"\u200E{(100)} 2024 {product.Name}";
内容的提问来源于stack exchange,提问作者Sandeep
相关产品推荐
相关产品推荐

