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

iText7中带背景色段落如何垂直居中?含中文字体适配

iText7 中文字体段落垂直居中问题解决方案

在iText7里用Canvas.ShowTextAligned设置段落垂直居中时,中文字体(如SimHei、微软雅黑)会出现明显下移,但自带西文字体正常。这是因为中文字体的排版基线、ascent/descent指标和西文字体存在差异,iText默认的居中计算逻辑没适配中文字体的特性。

下面提供两种适配所有字体的解决方案:

方案一:手动计算偏移修正居中位置

通过获取段落的实际布局尺寸,结合字体的排版参数,手动调整Y坐标来修正偏移:

string dest = "output.pdf";
using PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);

PageSize pageSize = PageSize.A4;
pdfDoc.SetDefaultPageSize(pageSize);

Color backgroundColor = ColorConstants.LIGHT_GRAY;
var currPage = pdfDoc.AddNewPage();
PdfCanvas pdfCanvas = new PdfCanvas(currPage);
pdfCanvas.SaveState()
    .SetFillColor(backgroundColor)
    .Rectangle(0, 0, pageSize.GetWidth(), pageSize.GetHeight())
    .Fill()
    .RestoreState();

string fontFolder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
FontProgramFactory.RegisterFont($"{fontFolder}\\SIMHEI.TTF", "simhei");
FontProgramFactory.RegisterFont($"{fontFolder}\\msyh.ttc,0", "msyh");

// 可切换测试西文字体或中文字体
//var font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
var font = PdfFontFactory.CreateRegisteredFont("simhei", PdfEncodings.IDENTITY_H, false);

Paragraph text = new Paragraph("你好Hello, World!A4_Blank_5P")
    .SetTextAlignment(TextAlignment.LEFT)
    .SetBackgroundColor(ColorConstants.WHITE)
    .SetFont(font);

// 计算段落的实际布局尺寸
var renderer = text.CreateRendererSubTree().SetParent(doc.GetRenderer());
LayoutResult result = renderer.Layout(new LayoutContext(new LayoutArea(1, pageSize)));
Rectangle rect = result.GetOccupiedArea().GetBBox();

// 计算需要调整的偏移:目标Y坐标减去段落高度的一半,再修正字体基线偏移
float targetY = 760f;
float adjustedY = targetY - (rect.GetHeight() / 2) + (font.GetFontProgram().GetFontMetrics().GetDescent() / 1000 * font.GetSize());

var canvas = new Canvas(pdfCanvas, currPage.GetPageSize());
canvas.ShowTextAligned(text, 34, adjustedY, 1, TextAlignment.LEFT, VerticalAlignment.MIDDLE, 0);

doc.Close();

核心逻辑是先通过布局渲染获取段落的实际占用区域,再结合字体的descent值调整Y坐标,抵消中文字体导致的下移。

方案二:使用Document布局引擎替代Canvas直接绘制

放弃Canvas.ShowTextAligned,改用iText的Document布局系统,让引擎自动处理字体差异:

string dest = "output.pdf";
using PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc, PageSize.A4);

// 设置页面背景
Color backgroundColor = ColorConstants.LIGHT_GRAY;
doc.Add(new AreaBreak());
var currPage = pdfDoc.GetLastPage();
PdfCanvas pdfCanvas = new PdfCanvas(currPage);
pdfCanvas.SaveState()
    .SetFillColor(backgroundColor)
    .Rectangle(0, 0, PageSize.A4.GetWidth(), PageSize.A4.GetHeight())
    .Fill()
    .RestoreState();

string fontFolder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
FontProgramFactory.RegisterFont($"{fontFolder}\\SIMHEI.TTF", "simhei");
FontProgramFactory.RegisterFont($"{fontFolder}\\msyh.ttc,0", "msyh");

// 可切换测试西文字体或中文字体
//var font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
var font = PdfFontFactory.CreateRegisteredFont("simhei", PdfEncodings.IDENTITY_H, false);

// 创建一个固定位置的Div来承载段落,设置垂直居中
Div container = new Div()
    .SetWidth(PageSize.A4.GetWidth() - 68) // 左右边距34
    .SetHeight(20) // 可根据需求调整高度
    .SetBackgroundColor(ColorConstants.WHITE)
    .SetVerticalAlignment(VerticalAlignment.MIDDLE)
    .SetMarginLeft(34)
    .SetFixedPosition(1, 34, 760 - 10, PageSize.A4.GetWidth() - 68, 20); // 固定位置,Y坐标为目标中心减去容器高度一半

container.Add(new Paragraph("你好Hello, World!A4_Blank_5P")
    .SetTextAlignment(TextAlignment.LEFT)
    .SetFont(font));

doc.Add(container);
doc.Close();

这种方式利用iText的布局容器(Div)的垂直居中属性,让引擎自动适配不同字体的排版规则,无需手动计算偏移。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:24:58