根据文本调整显示位置
This commit is contained in:
parent
8c298544b4
commit
e4b416d6fa
@ -810,7 +810,11 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
||||
ExtractPositionOffset(outerXml, paragraphData);
|
||||
}
|
||||
|
||||
_logger.LogDebug("最终提取的位置 - X: {X}, Y: {Y}", paragraphData.PositionX, paragraphData.PositionY);
|
||||
// 方法3: 提取文本框宽度
|
||||
ExtractWidthFromDrawing(outerXml, paragraphData);
|
||||
|
||||
_logger.LogDebug("最终提取的位置 - X: {X}, Y: {Y}, Width: {Width}",
|
||||
paragraphData.PositionX, paragraphData.PositionY, paragraphData.Width);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -818,6 +822,45 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 Drawing 对象 XML 中提取宽度信息
|
||||
/// </summary>
|
||||
private void ExtractWidthFromDrawing(string xml, ParagraphData paragraphData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 方法1: 查找 cx 属性,常见格式 ext cx="3000000"
|
||||
var cxMatch = System.Text.RegularExpressions.Regex.Match(xml, @"<wp:ext[^>]*?cx=[""'](\d+)[""']");
|
||||
if (cxMatch.Success)
|
||||
{
|
||||
if (long.TryParse(cxMatch.Groups[1].Value, out long cx))
|
||||
{
|
||||
paragraphData.Width = EmuToPoints(cx);
|
||||
_logger.LogDebug("提取到宽度 (EMU): {EMU}, (点): {Points}", cx, paragraphData.Width);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 方法2: 查找 extents cx 属性
|
||||
var extentsCxMatch = System.Text.RegularExpressions.Regex.Match(xml, @"extents\s*=\s*[\""'](?:\d+)\s*,\s*(\d+)[""']");
|
||||
if (extentsCxMatch.Success)
|
||||
{
|
||||
if (long.TryParse(extentsCxMatch.Groups[1].Value, out long cx))
|
||||
{
|
||||
paragraphData.Width = EmuToPoints(cx);
|
||||
_logger.LogDebug("提取到 extents 宽度 (EMU): {EMU}, (点): {Points}", cx, paragraphData.Width);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogDebug("未找到宽度信息,使用默认值");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "提取宽度信息失败");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 XML 中提取 simplePos 属性
|
||||
/// </summary>
|
||||
@ -1070,7 +1113,7 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
||||
for (int i = 0; i < documentData.Paragraphs.Count; i++)
|
||||
{
|
||||
var p = documentData.Paragraphs[i];
|
||||
_logger.LogInformation($" [{i}] 文本: {p.Text}, X: {p.PositionX}, Y: {p.PositionY}, 字号: {p.FontSize}");
|
||||
_logger.LogInformation($" [{i}] 文本: {p.Text}, X: {p.PositionX}, Y: {p.PositionY}, Width: {p.Width}, 字号: {p.FontSize}, 对齐: {p.Alignment}");
|
||||
}
|
||||
|
||||
var questDocument = QuestPDF.Fluent.Document.Create(container =>
|
||||
@ -1095,8 +1138,8 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
||||
.FitArea();
|
||||
}
|
||||
|
||||
// 最简单且工作的方案:使用正常的 Column 布局
|
||||
// 但通过跟踪和补偿累积高度来定位所有文本
|
||||
// 解决方案:保持文本框位置不变,在固定宽度容器内对齐
|
||||
// 这样文本是在文本框内部对齐,而不是移动文本框位置
|
||||
float cumulativeHeight = 0;
|
||||
|
||||
page.Content().Column(column =>
|
||||
@ -1107,35 +1150,58 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
||||
{
|
||||
var fontSize = paragraph.FontSize ?? 14;
|
||||
var isBold = paragraph.IsBold;
|
||||
|
||||
var text = paragraph.Text;
|
||||
|
||||
// X偏移+80保持不变
|
||||
// Y坐标减去之前所有文本占用的高度进行补偿
|
||||
float x = (float)(paragraph.PositionX ?? 50) + 90;
|
||||
float baseX = (float)(paragraph.PositionX ?? 50) + 90;
|
||||
float y = (float)(paragraph.PositionY ?? 50) + 75 - cumulativeHeight;
|
||||
|
||||
// 使用从 Word 中提取到的文本框宽度,如未提取到则使用默认值 300
|
||||
float textBoxWidth = (float)(paragraph.Width ?? 300);
|
||||
|
||||
_logger.LogInformation($"放置文本框: 文本={text}, baseX={baseX}, Y={y}, width={textBoxWidth}, alignment={paragraph.Alignment}");
|
||||
|
||||
_logger.LogInformation($"放置文本框: 文本={paragraph.Text}, X={x}, Y={y}, cumulativeHeight={cumulativeHeight}");
|
||||
|
||||
// 正常添加文本,不限制高度
|
||||
var element = column.Item()
|
||||
.TranslateX(x)
|
||||
// 创建元素并根据对齐方式设置
|
||||
var item = column.Item()
|
||||
.TranslateX(baseX)
|
||||
.TranslateY(y)
|
||||
.Text(paragraph.Text)
|
||||
.Width(textBoxWidth);
|
||||
|
||||
// 创建对齐的文本元素
|
||||
QuestPDF.Infrastructure.IContainer alignedContainer;
|
||||
switch (paragraph.Alignment?.ToLower())
|
||||
{
|
||||
case "center":
|
||||
alignedContainer = item.AlignCenter();
|
||||
break;
|
||||
case "right":
|
||||
alignedContainer = item.AlignRight();
|
||||
break;
|
||||
case "left":
|
||||
case "justify":
|
||||
default:
|
||||
alignedContainer = item.AlignLeft();
|
||||
break;
|
||||
}
|
||||
|
||||
// 添加文本并设置样式
|
||||
var textElement = alignedContainer
|
||||
.Text(text)
|
||||
.FontSize((float)fontSize)
|
||||
.FontColor(Colors.Black)
|
||||
.AlignLeft();
|
||||
|
||||
.FontColor(Colors.Black);
|
||||
|
||||
if (!string.IsNullOrEmpty(selectedFont))
|
||||
{
|
||||
element = element.FontFamily(selectedFont);
|
||||
textElement = textElement.FontFamily(selectedFont);
|
||||
}
|
||||
|
||||
if (isBold)
|
||||
{
|
||||
element = element.Bold();
|
||||
textElement = textElement.Bold();
|
||||
}
|
||||
|
||||
// 估算当前文本行的高度并累积
|
||||
// 通常一行文本高度大约是 font-size * 1.5
|
||||
cumulativeHeight += (float)(fontSize * 1.5f);
|
||||
}
|
||||
});
|
||||
@ -1418,6 +1484,7 @@ public class ParagraphData
|
||||
public string Style { get; set; } = "normal"; // normal, heading, subheading
|
||||
public double? PositionX { get; set; } = null;
|
||||
public double? PositionY { get; set; } = null;
|
||||
public double? Width { get; set; } = null; // 文本框宽度
|
||||
public double? FontSize { get; set; } = null;
|
||||
public string Alignment { get; set; } = "left"; // left, center, right
|
||||
public bool IsBold { get; set; } = false;
|
||||
|
||||
@ -911,6 +911,11 @@
|
||||
从 Drawing 对象中提取位置信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.ExtractWidthFromDrawing(System.String,YD_Event.Application.Certificate.ParagraphData)">
|
||||
<summary>
|
||||
从 Drawing 对象 XML 中提取宽度信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.ExtractSimplePosition(System.String,YD_Event.Application.Certificate.ParagraphData)">
|
||||
<summary>
|
||||
从 XML 中提取 simplePos 属性
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user