\n");
// 按 zIndex 升序渲染(低 zIndex 先画,高 zIndex 覆盖在上层)
var sortedElements = elements.OfType
()
.OrderBy(el => el?["zIndex"]?.GetValue() ?? 0)
.ToList();
foreach (var el in sortedElements)
{
if (el == null) continue;
var elHtml = RenderElement(el, data, widthMm, heightMm, pageCount, mt, mb, elements,
repeatHeaderByPage, headerBandHeight, reportHeaderId, headerVisible);
if (!string.IsNullOrEmpty(elHtml))
sb.Append(elHtml);
}
for (var i = 1; i < pageCount; i++)
{
var sepTop = (i * heightMm).ToString("0.###", CultureInfo.InvariantCulture);
sb.Append($"\n");
sb.Append($"\n");
}
sb.Append(" \n");
return sb.ToString();
}
// ─── 元素渲染分发 ──────────────────────────────────────────────────────
private static string RenderElement(
JsonNode el, JsonObject data,
double pageWidthMm, double pageHeightMm, int totalPages,
double marginTopMm, double marginBottomMm, JsonArray allElements,
bool repeatHeaderByPage = false, double headerBandHeight = 0d,
string reportHeaderId = "", bool headerVisible = true)
{
// visible=false 的元素跳过(与前端一致)
if (string.Equals(ReadAsString(el["visible"]), "false", StringComparison.OrdinalIgnoreCase))
return string.Empty;
var type = ReadAsString(el["type"], "text");
var x = el["x"]?.GetValue