根据文本调整显示位置
This commit is contained in:
parent
8c298544b4
commit
e4b416d6fa
@ -810,7 +810,11 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
ExtractPositionOffset(outerXml, paragraphData);
|
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)
|
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>
|
/// <summary>
|
||||||
/// 从 XML 中提取 simplePos 属性
|
/// 从 XML 中提取 simplePos 属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1070,7 +1113,7 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
for (int i = 0; i < documentData.Paragraphs.Count; i++)
|
for (int i = 0; i < documentData.Paragraphs.Count; i++)
|
||||||
{
|
{
|
||||||
var p = documentData.Paragraphs[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 =>
|
var questDocument = QuestPDF.Fluent.Document.Create(container =>
|
||||||
@ -1095,8 +1138,8 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
.FitArea();
|
.FitArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最简单且工作的方案:使用正常的 Column 布局
|
// 解决方案:保持文本框位置不变,在固定宽度容器内对齐
|
||||||
// 但通过跟踪和补偿累积高度来定位所有文本
|
// 这样文本是在文本框内部对齐,而不是移动文本框位置
|
||||||
float cumulativeHeight = 0;
|
float cumulativeHeight = 0;
|
||||||
|
|
||||||
page.Content().Column(column =>
|
page.Content().Column(column =>
|
||||||
@ -1107,35 +1150,58 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
{
|
{
|
||||||
var fontSize = paragraph.FontSize ?? 14;
|
var fontSize = paragraph.FontSize ?? 14;
|
||||||
var isBold = paragraph.IsBold;
|
var isBold = paragraph.IsBold;
|
||||||
|
var text = paragraph.Text;
|
||||||
|
|
||||||
// X偏移+80保持不变
|
// X偏移+80保持不变
|
||||||
// Y坐标减去之前所有文本占用的高度进行补偿
|
// Y坐标减去之前所有文本占用的高度进行补偿
|
||||||
float x = (float)(paragraph.PositionX ?? 50) + 90;
|
float baseX = (float)(paragraph.PositionX ?? 50) + 90;
|
||||||
float y = (float)(paragraph.PositionY ?? 50) + 75 - cumulativeHeight;
|
float y = (float)(paragraph.PositionY ?? 50) + 75 - cumulativeHeight;
|
||||||
|
|
||||||
_logger.LogInformation($"放置文本框: 文本={paragraph.Text}, X={x}, Y={y}, cumulativeHeight={cumulativeHeight}");
|
// 使用从 Word 中提取到的文本框宽度,如未提取到则使用默认值 300
|
||||||
|
float textBoxWidth = (float)(paragraph.Width ?? 300);
|
||||||
|
|
||||||
// 正常添加文本,不限制高度
|
_logger.LogInformation($"放置文本框: 文本={text}, baseX={baseX}, Y={y}, width={textBoxWidth}, alignment={paragraph.Alignment}");
|
||||||
var element = column.Item()
|
|
||||||
.TranslateX(x)
|
// 创建元素并根据对齐方式设置
|
||||||
|
var item = column.Item()
|
||||||
|
.TranslateX(baseX)
|
||||||
.TranslateY(y)
|
.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)
|
.FontSize((float)fontSize)
|
||||||
.FontColor(Colors.Black)
|
.FontColor(Colors.Black);
|
||||||
.AlignLeft();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(selectedFont))
|
if (!string.IsNullOrEmpty(selectedFont))
|
||||||
{
|
{
|
||||||
element = element.FontFamily(selectedFont);
|
textElement = textElement.FontFamily(selectedFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBold)
|
if (isBold)
|
||||||
{
|
{
|
||||||
element = element.Bold();
|
textElement = textElement.Bold();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 估算当前文本行的高度并累积
|
// 估算当前文本行的高度并累积
|
||||||
// 通常一行文本高度大约是 font-size * 1.5
|
|
||||||
cumulativeHeight += (float)(fontSize * 1.5f);
|
cumulativeHeight += (float)(fontSize * 1.5f);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1418,6 +1484,7 @@ public class ParagraphData
|
|||||||
public string Style { get; set; } = "normal"; // normal, heading, subheading
|
public string Style { get; set; } = "normal"; // normal, heading, subheading
|
||||||
public double? PositionX { get; set; } = null;
|
public double? PositionX { get; set; } = null;
|
||||||
public double? PositionY { get; set; } = null;
|
public double? PositionY { get; set; } = null;
|
||||||
|
public double? Width { get; set; } = null; // 文本框宽度
|
||||||
public double? FontSize { get; set; } = null;
|
public double? FontSize { get; set; } = null;
|
||||||
public string Alignment { get; set; } = "left"; // left, center, right
|
public string Alignment { get; set; } = "left"; // left, center, right
|
||||||
public bool IsBold { get; set; } = false;
|
public bool IsBold { get; set; } = false;
|
||||||
|
|||||||
@ -911,6 +911,11 @@
|
|||||||
从 Drawing 对象中提取位置信息
|
从 Drawing 对象中提取位置信息
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</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)">
|
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.ExtractSimplePosition(System.String,YD_Event.Application.Certificate.ParagraphData)">
|
||||||
<summary>
|
<summary>
|
||||||
从 XML 中提取 simplePos 属性
|
从 XML 中提取 simplePos 属性
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user