Flutter中PDF预览SVG报RangeError(length)错误求助
问题描述
在Flutter中尝试通过PdfPreview加载SVG生成PDF时出现红屏错误,错误信息如下:
RangeError (length): Invalid value: Not in inclusive range 0..11399: 11403
怀疑是SVG中base64格式的图片导致问题,相关代码如下:
import 'package:flutter/material.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:printing/printing.dart'; class PrintTestTicketsScreen extends StatelessWidget { final String svgString; const PrintTestTicketsScreen({super.key, required this.svgString}); @override Widget build(BuildContext context) { final doc = pw.Document(verbose: true); doc.addPage(pw.Page(build: (pw.Context context) { return pw.SvgImage( svg: testSvgString, ); })); return PdfPreview( build: (format) => doc.save(), ); } } String testSvgString = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="210mm" height="297mm" viewBox="0 0 210 297" style="background-color: #ffffffff;" xmlns="http://www.w3.org/2000/svg"><text x="126" y="215" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Event Layout</text><text x="51" y="52" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Event 42</text><text x="5" y="53" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Event:</text><text x="51" y="33" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Rico DTM Hockemheimring</text><text x="6" y="34" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Serie:</text><image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQMAAABDsxw2AAAABlBMVEX///8AAABVwtN+AAABk0lEQVR42uyZO5LyMBCEm3JAqCPoKD6afTQfxUdQ6IDy/DUP8ZuizAJSbW3QHfAwX4RGrZ4RKIqiqD+tq7jKoK8LksiOeCbEmrGbveUCQGTJsg07ZNFnF2IdsIv++7kMO4BRRG6A4nIj1hHTVZjHFbBVINYfU7mHEOuGhYdYkSNHkZ9aDbHPsPsJuFuRJ7PoFwclsU+wo2Qepfyc5Yh1x67uKFm3AKZqOeNafyDWiMXj2AtxUPomIdaKQZuT2VdBi1y2QQRmOcTasau1fAuS5xGk7b4KO4g1Y2oV05I11dlqbEM9Jom1Y6iTCyvyiHkne4HYx5jX8ujh2YrbMCkg1gGDD4bMQ6xZ8aZwTY89ILHvsLDobJYxiZToWko0h8SasP9esnuO8w8+5iTWih1bbPMSDxjahZxNMIj1xw4zfEzigw77/rhYxL7EHqaguWa88jzBINaC1RStxR1XJcS6YYP3gh5Mlvx0f0rsO+xwfzpHzAOQtvNrVmLvY8cZ/t07xjW9GPUTexujKIqiflX/AgAA//9+34hK7/BreQAAAABJRU5ErkJggg==" x="146" y="233" width="50" height="50" /><text x="52" y="93" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Erwachsene</text><text x="5" y="92" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Preis:</text><text x="52" y="73" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Sektion C</text><text x="5" y="73" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Section:</text><text x="6" y="138" style="fill: #000000ff; font-size: 12px; font-weight: 400;"></text></svg>';
问题分析与解决
核心问题:SVG字符串的转义字符导致解析错误
你提供的testSvgString使用了HTML转义字符(如<代替<,"代替"),而pdf包的pw.SvgImage需要原始的SVG格式字符串,转义字符会让解析器处理时出现索引越界,触发RangeError。
修改方案
- 还原SVG字符串的转义字符
将所有<替换为<,"替换为",确保SVG结构能被正确解析。 - 调整PDF文档构建逻辑
将文档创建移到PdfPreview的build回调中,避免在build方法重复创建文档,符合异步构建要求。 - 修正参数引用
使用组件传入的svgString而非硬编码的testSvgString,保证组件复用性。
修改后的代码
import 'package:flutter/material.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:printing/printing.dart'; class PrintTestTicketsScreen extends StatelessWidget { final String svgString; const PrintTestTicketsScreen({super.key, required this.svgString}); @override Widget build(BuildContext context) { return PdfPreview( build: (format) async { final doc = pw.Document(verbose: true); doc.addPage(pw.Page(build: (pw.Context context) { return pw.SvgImage( svg: svgString, ); })); return doc.save(); }, ); } } // 还原转义后的SVG字符串 String testSvgString = '''<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="210mm" height="297mm" viewBox="0 0 210 297" style="background-color: #ffffffff;" xmlns="http://www.w3.org/2000/svg"> <text x="126" y="215" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Event Layout</text> <text x="51" y="52" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Event 42</text> <text x="5" y="53" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Event:</text> <text x="51" y="33" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Rico DTM Hockemheimring</text> <text x="6" y="34" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Serie:</text> <image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQMAAABDsxw2AAAABlBMVEX///8AAABVwtN+AAABk0lEQVR42uyZO5LyMBCEm3JAqCPoKD6afTQfxUdQ6IDy/DUP8ZuizAJSbW3QHfAwX4RGrZ4RKIqiqD+tq7jKoK8LksiOeCbEmrGbveUCQGTJsg07ZNFnF2IdsIv++7kMO4BRRG6A4nIj1hHTVZjHFbBVINYfU7mHEOuGhYdYkSNHkZ9aDbHPsPsJuFuRJ7PoFwclsU+wo2Qepfyc5Yh1x67uKFm3AKZqOeNafyDWiMXj2AtxUPomIdaKQZuT2VdBi1y2QQRmOcTasau1fAuS5xGk7b4KO4g1Y2oV05I11dlqbEM9Jom1Y6iTCyvyiHkne4HYx5jX8ujh2YrbMCkg1gGDD4bMQ6xZ8aZwTY89ILHvsLDobJYxiZToWko0h8SasP9esnuO8w8+5iTWih1bbPMSDxjahZxNMIj1xw4zfEzigw77/rhYxL7EHqaguWa88jzBINaC1RStxR1XJcS6YYP3gh5Mlvx0f0rsO+xwfzpHzAOQtvNrVmLvY8cZ/t07xjW9GPUTexujKIqiflX/AgAA//9+34hK7/BreQAAAABJRU5ErkJggg==" x="146" y="233" width="50" height="50" /> <text x="52" y="93" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Erwachsene</text> <text x="5" y="92" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Preis:</text> <text x="52" y="73" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Sektion C</text> <text x="5" y="73" style="fill: #000000ff; font-size: 12px; font-weight: 400;">Section:</text> <text x="6" y="138" style="fill: #000000ff; font-size: 12px; font-weight: 400;"></text> </svg>''';
额外排查建议
- 验证base64图片完整性:用在线工具解码base64字符串,确认图片能正常显示。
- 更新依赖包:确保
pdf和printing包为最新版本,修复旧版本可能存在的SVG解析bug。 - 调整尺寸单位:若仍有问题,可尝试将SVG中的
mm单位转换为pt或px,避免解析器对单位处理异常。
内容的提问来源于stack exchange,提问作者Haissem55
相关产品推荐
相关产品推荐

