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

Flutter生成PDF时Android端马拉雅拉姆语字体渲染异常如何解决

Flutter Printing插件HTML转PDF Android端马拉雅拉姆语渲染异常修复

问题表现

  • App内已引入马拉雅拉姆语自定义字体,Android、iOS端应用页面内文字渲染完全正常
  • 调用Printing.convertHtml实现HTML转PDF功能时,英文内容生成效果正常,马拉雅拉姆语等非英语内容在Android实体设备上无法正常显示,仅展示英文字符
  • 异常仅出现在Android实体设备,iOS模拟器(iPhone 13)上PDF渲染无问题
  • 异常效果参考:
    Android端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内携带的字体资源完成渲染。

  1. 读取项目内的马拉雅拉姆语字体文件,转换为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());
  1. 拼接带内嵌字体声明的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>
''';
  1. 替换原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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:18:13