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

如何修复iText7+Canvas生成PDF的元素重叠并启用text-anchor:end

iText7转换SVG到PDF的两个问题:元素重叠与text-anchor:end启用

我使用以下PdfGeneratorService服务类,通过iText7和Canvas将SVG文件生成PDF,但生成的PDF出现元素重叠问题。此外,我需要启用text-anchor:end属性,已知iText7文档中有对应选项,但不知如何在代码中应用。

服务类代码

public class PdfGeneratorService : IPdfGeneratorService
{
    public byte[] GeneratePdfFromSvgFile(IFormFile svgFile, string colorMode)
    {
        using (StreamReader reader = new StreamReader(svgFile.OpenReadStream()))
        {
            string svgContent = reader.ReadToEnd();

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(svgFile.OpenReadStream());

            if (xmlDocument.DocumentElement != null && xmlDocument.DocumentElement.Name == "svg")
            {
                using (MemoryStream pdfStream = new MemoryStream())
                {
                    PdfDocument doc = new PdfDocument(
                        new PdfWriter(pdfStream,
                        new WriterProperties().SetCompressionLevel(0)));

                    PageSize pageSize = PageSize.A4.Rotate();
                    doc.SetDefaultPageSize(pageSize);

                    XmlDocument modifiedXmlDocument = SvgColorTransformer.ApplyColorTransformation(xmlDocument, colorMode);
                    string modifiedSvgContent = modifiedXmlDocument.OuterXml;

                    foreach (string pageSvgContent in GeneratePages.GenerateSvgPages(modifiedSvgContent))
                    {
                        doc.AddNewPage();

                        PdfCanvas canvas = new PdfCanvas(doc.GetLastPage());

                        // Scale transformation
                        float scaleX = .704f; // Adjust as needed
                        float scaleY = .704f; // Adjust as needed

                        Rectangle pageRectangle = doc.GetLastPage().GetPageSize();
                        float svgWidth = pageRectangle.GetWidth() * scaleX;
                        float svgHeight = pageRectangle.GetHeight() * scaleY;
                        float translateX = (pageRectangle.GetWidth() - svgWidth) / 99;
                        float translateY = (pageRectangle.GetHeight() - svgHeight) / 90;

                        // Apply the scaling transformation to the canvas
                        canvas.ConcatMatrix(scaleX, 0, 0, scaleY, translateX, translateY);

                        string adjustedSvgContent = AdjustSvg.AdjustSvgContent(pageSvgContent, translateX, translateY, scaleX, scaleY);

                        // Draw the scaled SVG content on the canvas
                        SvgConverter.DrawOnDocument(adjustedSvgContent, doc, 1);
                    }

                    doc.Close();

                    return pdfStream.ToArray();
                }
            }
            else
            {
                throw new BadRequestException("Invalid SVG format");
            }
        }
    }
}

更新内容

  • 导出PDF前的SVG:元素布局规整,文本位置符合预期
  • 导出PDF后的效果:出现元素重叠现象,文本位置偏移

问题解决方案

1. 启用text-anchor:end属性

iText7的SvgConverter支持通过配置SvgConverterProperties开启SVG文本锚点属性,替换原有的SvgConverter.DrawOnDocument调用即可:

// 创建SVG转换配置并启用text-anchor支持
SvgConverterProperties properties = new SvgConverterProperties();
properties.SetEnableTextAnchor(true);
// 使用配置渲染SVG到PDF指定页面
SvgConverter.DrawOnDocument(adjustedSvgContent, doc, doc.GetNumberOfPages(), properties);

2. 解决元素重叠问题

元素重叠多由双重变换、分页逻辑或尺寸匹配问题导致,可尝试以下调整:

  • 移除重复变换:当前代码同时对PdfCanvas做矩阵变换,又调用AdjustSvg.AdjustSvgContent修改SVG内容,双重变换易引发布局错乱。建议只保留一种变换方式,比如通过SvgConverterProperties设置渲染尺寸,而非操作画布矩阵。
  • 检查分页逻辑:GeneratePages.GenerateSvgPages的分页处理可能未正确计算元素边界,导致分页后SVG元素重叠。需验证分页时是否正确分割SVG的viewBox或元素坐标。
  • 匹配SVG与PDF尺寸:通过SvgConverterProperties指定SVG渲染的目标尺寸,确保与PDF页面可用区域匹配:
properties.SetDestinationSize(new Rectangle(svgWidth, svgHeight));

内容的提问来源于stack exchange,提问作者Tommy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:53:22