This commit is contained in:
Курнат Андрей
2026-03-23 21:24:09 +03:00
parent bf9f54f91c
commit 74d793948e
471 changed files with 6560 additions and 22 deletions

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
namespace XLAB2
@@ -12,8 +13,11 @@ namespace XLAB2
private const int OpenPsvTableColumnCount = 7;
private const int ClosePsvTableColumnCount = 12;
private const int PrintDialogId = 88;
private const int WordActiveEndAdjustedPageNumber = 1;
private const int WordAlertsNone = 0;
private const int WordParagraphTrue = -1;
private const int WordCloseDoNotSaveChanges = 0;
private const int WordStatisticPages = 2;
public void PrintDocument(PsvDocumentSummary document, IReadOnlyList<PsvDocumentLine> lines)
{
@@ -232,6 +236,9 @@ namespace XLAB2
ReleaseComObject(row);
}
}
// If trailing document text spills onto a new page, move the last table row with it.
EnsureTableSpillsToNextPage(document, table);
}
finally
{
@@ -239,6 +246,60 @@ namespace XLAB2
}
}
private static void EnsureTableSpillsToNextPage(dynamic document, dynamic table)
{
if (document == null || table == null)
{
return;
}
var rowCount = Convert.ToInt32(table.Rows.Count, CultureInfo.InvariantCulture);
if (rowCount <= 1)
{
return;
}
RepaginateDocument(document);
var totalPages = InvokeComIntMethod(document, "ComputeStatistics", WordStatisticPages);
if (totalPages <= 1)
{
return;
}
dynamic lastRow = null;
dynamic firstCell = null;
dynamic lastRowRange = null;
dynamic firstCellRange = null;
dynamic paragraphFormat = null;
try
{
lastRow = table.Rows.Item(rowCount);
lastRowRange = lastRow.Range;
var lastRowPage = GetRangePageNumber(lastRowRange);
if (lastRowPage >= totalPages)
{
return;
}
firstCell = lastRow.Cells.Item(1);
firstCellRange = firstCell.Range;
paragraphFormat = firstCellRange.ParagraphFormat;
paragraphFormat.PageBreakBefore = WordParagraphTrue;
RepaginateDocument(document);
}
finally
{
ReleaseComObject(paragraphFormat);
ReleaseComObject(firstCellRange);
ReleaseComObject(lastRowRange);
ReleaseComObject(firstCell);
ReleaseComObject(lastRow);
}
}
private static void EnsurePsvTableLayout(dynamic table, int expectedColumnCount)
{
if (table == null)
@@ -268,6 +329,16 @@ namespace XLAB2
}
}
private static int GetRangePageNumber(object range)
{
return InvokeComIndexedIntProperty(range, "Information", WordActiveEndAdjustedPageNumber);
}
private static void RepaginateDocument(object document)
{
InvokeComMethod(document, "Repaginate");
}
private static void SetCellText(dynamic row, int columnIndex, string value, bool centerAlign)
{
dynamic cell = null;
@@ -317,6 +388,55 @@ namespace XLAB2
}
}
private static int InvokeComIndexedIntProperty(object target, string propertyName, object argument)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
return Convert.ToInt32(
target.GetType().InvokeMember(
propertyName,
BindingFlags.GetProperty,
null,
target,
new[] { argument }),
CultureInfo.InvariantCulture);
}
private static int InvokeComIntMethod(object target, string methodName, object argument)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
return Convert.ToInt32(
target.GetType().InvokeMember(
methodName,
BindingFlags.InvokeMethod,
null,
target,
new[] { argument }),
CultureInfo.InvariantCulture);
}
private static void InvokeComMethod(object target, string methodName)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
target.GetType().InvokeMember(
methodName,
BindingFlags.InvokeMethod,
null,
target,
Array.Empty<object>());
}
private static IReadOnlyList<PrintedGroupRow> BuildPrintedGroups(IEnumerable<PsvDocumentLine> lines, bool includeClosedDetails)
{
return (lines ?? Enumerable.Empty<PsvDocumentLine>())
@@ -378,7 +498,7 @@ namespace XLAB2
return string.Empty;
}
if (serialNumbers.Count > 3)
if (serialNumbers.Count > 10)
{
return string.Format(CultureInfo.InvariantCulture, "{0} зав. номеров", serialNumbers.Count);
}