C#使用iText将SVG转PDF时显示不全、格式异常的解决方法
iText实现SVG转PDF显示不全、格式错乱问题修复
常见问题根源
- 流操作逻辑有漏洞:使用
File.Open打开SVG流之后,没有重置读取位置,也没有自动释放流的逻辑,iText读取的时候经常会从流的中间位置开始读,自然会出现内容截断、不全的问题 - 用了最简化的转换API:直接调用
SvgConverter.CreatePdf的无参重载,这个方法用的是默认解析规则,不会自动适配SVG自带的视口、缩放比例,遇到带外部资源的SVG就会渲染错位 - 页面尺寸不匹配:
CreatePdf默认会把输出PDF页面设为A4大小,不管SVG本身的尺寸是多少,超出A4范围的内容会直接被裁掉,这是显示不全的核心原因 - 渲染适配没做:没有配置字体、资源加载规则,遇到SVG里用的自定义字体、内嵌图片的时候,iText加载失败就会出现格式错乱
分步修复实现
对应当前的WinForm代码,可按照以下逻辑调整,解决显示异常问题:
- 用
using代码块自动管理文件流生命周期,避免句柄占用、读写位置偏移 - 显式重置SVG流的读取位置到文件开头,防止读取偏移
- 自定义SVG解析配置,指定本地资源加载路径、字体渲染规则,解决外部资源缺失导致的内容不全
- 提前解析SVG的实际渲染尺寸,创建完全匹配SVG大小的PDF页面,消除内容裁切问题
修复后核心代码
// 需补充引入的命名空间: // iText.Kernel.Geom; // iText.Svg.Converter; // iText.Svg.Processors.Impl; private void button1_Click(object sender, EventArgs e) { // 自动释放流资源,避免句柄占用 using (FileStream svgStream = new FileStream("1/1.svg", FileMode.Open, FileAccess.Read)) { // 重置流读取位置到文件开头 svgStream.Position = 0; // 配置SVG解析规则 SvgConverterProperties converterConfig = new SvgConverterProperties(); // 指定SVG同目录为资源加载根路径,解决外链资源缺失问题 converterConfig.SetBaseUri(Path.GetFullPath("1/")); // 加载系统字体适配,避免字体替换导致的格式错乱 converterConfig.SetFontProvider(new iText.IO.Font.FontProvider()); // 解析获取SVG实际渲染尺寸 SvgImage parsedSvg = SvgConverter.CreateSvgImage(svgStream, converterConfig); float realSvgWidth = parsedSvg.GetImageScaledWidth(); float realSvgHeight = parsedSvg.GetImageScaledHeight(); // 创建匹配SVG尺寸的PDF输出 using (FileStream outputPdfStream = new FileStream("output.pdf", FileMode.Create, FileAccess.ReadWrite)) { using (PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outputPdfStream))) { // 新建和SVG尺寸完全一致的页面,避免内容裁切 pdfDoc.AddNewPage(new PageSize(realSvgWidth, realSvgHeight)); // 将SVG直接绘制到页面,不做强制缩放 SvgConverter.DrawOnDocument(svgStream, pdfDoc, 1, converterConfig); } } } }
附加排查注意事项
- 版本适配:建议将iText升级到7.2.0及以上稳定版本,低版本对SVG2.0特性(渐变、滤镜、复杂路径、内嵌位图)存在已知的解析缺陷,是导致格式错乱的常见原因
- 资源校验:如果SVG内引用了外部的字体、图片资源,需将对应资源下载到与SVG同目录,配合代码中的
SetBaseUri配置保证资源能被正常加载,避免出现空白、内容缺失 - 拼写修正:原代码的输出文件名
autput.pdf存在拼写错误,修正为output.pdf避免找错文件
内容的提问来源于stack exchange,提问作者Jakob Ofner
相关产品推荐
相关产品推荐

