diff --git a/YD_Event.Application/Certificate/CertificateGenerateService.cs b/YD_Event.Application/Certificate/CertificateGenerateService.cs
index c96250d..c0c0acb 100644
--- a/YD_Event.Application/Certificate/CertificateGenerateService.cs
+++ b/YD_Event.Application/Certificate/CertificateGenerateService.cs
@@ -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
}
}
+ ///
+ /// 从 Drawing 对象 XML 中提取宽度信息
+ ///
+ private void ExtractWidthFromDrawing(string xml, ParagraphData paragraphData)
+ {
+ try
+ {
+ // 方法1: 查找 cx 属性,常见格式 ext cx="3000000"
+ var cxMatch = System.Text.RegularExpressions.Regex.Match(xml, @"]*?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, "提取宽度信息失败");
+ }
+ }
+
///
/// 从 XML 中提取 simplePos 属性
///
@@ -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;
diff --git a/YD_Event.Application/YD_Event.Application.xml b/YD_Event.Application/YD_Event.Application.xml
index 8c9f53f..65d4518 100644
--- a/YD_Event.Application/YD_Event.Application.xml
+++ b/YD_Event.Application/YD_Event.Application.xml
@@ -911,6 +911,11 @@
从 Drawing 对象中提取位置信息
+
+
+ 从 Drawing 对象 XML 中提取宽度信息
+
+
从 XML 中提取 simplePos 属性