Flutter生成PDF时Android端马拉雅拉姆语字体渲染异常如何解决
Flutter Printing插件HTML转PDF Android端马拉雅拉姆语渲染异常修复
问题表现
- App内已引入马拉雅拉姆语自定义字体,Android、iOS端应用页面内文字渲染完全正常
- 调用
Printing.convertHtml实现HTML转PDF功能时,英文内容生成效果正常,马拉雅拉姆语等非英语内容在Android实体设备上无法正常显示,仅展示英文字符 - 异常仅出现在Android实体设备,iOS模拟器(iPhone 13)上PDF渲染无问题
- 异常效果参考:

问题复现代码
await Printing.convertHtml( html:content ).then((value) { bytes1=value; // showLoader(); Navigator.push( NavigationService.navigationKey.currentContext!, MaterialPageRoute(builder: (context) => PdfViewer(doc: value), ) ); });
问题原因
Printing.convertHtml底层渲染逻辑存在平台差异:
- iOS端基于系统WKWebView渲染HTML,可直接读取App内已注册的自定义字体,因此非英文字符渲染正常
- Android端基于系统WebView渲染HTML,默认无法读取App包内assets目录下未做内嵌声明的自定义字体,匹配不到对应语种字体时会自动降级,最终出现非英文字符渲染失败的问题
修复方案
将自定义字体以base64格式内嵌到待转换的HTML内容中,让WebView渲染时无需依赖系统或App全局注册的字体,直接加载HTML内携带的字体资源完成渲染。
- 读取项目内的马拉雅拉姆语字体文件,转换为base64编码
import 'dart:convert'; import 'package:flutter/services.dart'; // 替换为你项目中实际的马拉雅拉姆语字体路径 final fontByteData = await rootBundle.load('assets/fonts/your_malayalam_font.ttf'); final fontBase64Str = base64Encode(fontByteData.buffer.asUint8List());
- 拼接带内嵌字体声明的HTML内容,注意添加马拉雅拉姆语所需的连字渲染配置
final pdfHtmlContent = ''' <!DOCTYPE html> <html lang="ml"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> @font-face { font-family: 'CustomMalayalamFont'; src: url(data:font/truetype;charset=utf-8;base64,$fontBase64Str) format('truetype'); font-weight: normal; font-style: normal; } * { margin: 0; padding: 0; font-family: 'CustomMalayalamFont', sans-serif; // 配置文字渲染规则,保证马拉雅拉姆语的连字、组合字符显示正常 text-rendering: optimizeLegibility; font-feature-settings: "kern" 1; } </style> </head> <body> $content // 替换为你原本需要渲染的业务HTML内容 </body> </html> ''';
- 替换原convertHtml调用的入参,传入拼接完成的带内嵌字体的HTML内容
await Printing.convertHtml(html: pdfHtmlContent).then((value) { bytes1 = value; Navigator.push( NavigationService.navigationKey.currentContext!, MaterialPageRoute(builder: (context) => PdfViewer(doc: value)), ); });
注意事项
- 如果自定义字体文件体积过大,建议先裁剪字体,仅保留马拉雅拉姆语对应的字符子集,避免base64内容过长导致HTML加载速度变慢
- 不要依赖Android系统预装的南亚语言字体,不同厂商的系统预装字体差异极大,内嵌字体是唯一能保证全Android机型渲染效果一致的方案
- 若部分Android机型出现字体渲染错位问题,可在HTML的meta标签中关闭用户缩放,适配WebView视口尺寸即可
内容的提问来源于stack exchange,提问作者Shemeer
相关产品推荐
相关产品推荐

