Я написал класс, чтобы сложить несколько FixedPage
в один FixedPage
, он отлично работает.
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Markup;
using System.Windows.Controls;
using System.Windows.Documents;
namespace PreviewHelper
{
internal enum DocumentOrientation
{
Portrait,
Landscape
}
internal class MultiPagesPerSheetHelper
{
private readonly int _pagesPerSheet;
private readonly Size _innerPageSize;
private readonly FixedDocument _document;
private readonly DocumentOrientation _documentOrientation;
private readonly List<int> _allowedPagesPerSheetCount = new List<int> { 1, 2, 4, 6, 9, 16 };
private readonly List<Size> _allowedPagesPerSheetArrange = new List<Size> { new Size(1, 1), new Size(1, 2), new Size(2, 2), new Size(2, 3), new Size(3, 3), new Size(4, 4) };
public MultiPagesPerSheetHelper()
{
_document = null;
_pagesPerSheet = 0;
_innerPageSize = new Size();
_documentOrientation = DocumentOrientation.Portrait;
}
public MultiPagesPerSheetHelper(int pagesPerSheet, FixedDocument document)
{
_document = document;
_pagesPerSheet = pagesPerSheet;
_innerPageSize = new Size();
_documentOrientation = DocumentOrientation.Portrait;
}
public MultiPagesPerSheetHelper(int pagesPerSheet, FixedDocument document, Size innerPageSize)
{
_document = document;
_pagesPerSheet = pagesPerSheet;
_innerPageSize = innerPageSize;
_documentOrientation = DocumentOrientation.Portrait;
}
public MultiPagesPerSheetHelper(int pagesPerSheet, FixedDocument document, Size innerPageSize, DocumentOrientation documentOrientation)
{
_document = document;
_pagesPerSheet = pagesPerSheet;
_innerPageSize = innerPageSize;
_documentOrientation = documentOrientation;
}
public FixedDocument GetMultiPagesPerSheetDocument()
{
if (_document == null && _document.Pages.Count == 0 && _pagesPerSheet == 0)
{
return new FixedDocument();
}
if (_allowedPagesPerSheetCount.Contains(_pagesPerSheet) == false)
{
return new FixedDocument();
}
FixedDocument doc = new FixedDocument();
doc.DocumentPaginator.PageSize = _document.DocumentPaginator.PageSize;
int currentPageCount = 0;
int pagesPerSheetIndex = _allowedPagesPerSheetCount.IndexOf(_pagesPerSheet);
int arrangeRows;
int arrangeColumns;
if (_documentOrientation == DocumentOrientation.Portrait)
{
arrangeRows = (int)_allowedPagesPerSheetArrange[pagesPerSheetIndex].Height;
arrangeColumns = (int)_allowedPagesPerSheetArrange[pagesPerSheetIndex].Width;
}
else
{
arrangeRows = (int)_allowedPagesPerSheetArrange[pagesPerSheetIndex].Width;
arrangeColumns = (int)_allowedPagesPerSheetArrange[pagesPerSheetIndex].Height;
}
double innerPageHeight = doc.DocumentPaginator.PageSize.Height / arrangeRows;
double innerPageWidth = doc.DocumentPaginator.PageSize.Width / arrangeColumns;
while (currentPageCount < _document.Pages.Count)
{
FixedPage outerPage = new FixedPage
{
Width = doc.DocumentPaginator.PageSize.Width,
Height = doc.DocumentPaginator.PageSize.Height
};
Grid outergrid = new Grid()
{
Width = outerPage.Width,
Height = outerPage.Height,
};
for (int i = 0; i < arrangeRows; i++)
{
outergrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
}
for (int i = 0; i < arrangeColumns; i++)
{
outergrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
}
for (int i = 0; i < arrangeRows; i++)
{
for (int j = 0; j < arrangeColumns && currentPageCount < _document.Pages.Count; j++)
{
Grid innerGrid = new Grid()
{
Width = innerPageWidth,
Height = innerPageHeight,
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Center
};
innerGrid.SetValue(Grid.RowProperty, i);
innerGrid.SetValue(Grid.ColumnProperty, j);
string xaml = XamlWriter.Save(_document.Pages[currentPageCount].Child);
FixedPage innerPage = XamlReader.Parse(xaml) as FixedPage;
if (_innerPageSize.Width == 0 || _innerPageSize.Height == 0 || _innerPageSize.Width == double.NaN || _innerPageSize.Height == double.NaN)
{
innerPage.Width = outerPage.Width;
innerPage.Height = outerPage.Width;
}
else
{
innerPage.Width = _innerPageSize.Width;
innerPage.Height = _innerPageSize.Height;
}
innerPage.VerticalAlignment = VerticalAlignment.Center;
innerPage.HorizontalAlignment = HorizontalAlignment.Center;
double widthRatio;
double heightRatio;
widthRatio = innerPageWidth / innerPage.Width;
heightRatio = innerPageHeight / innerPage.Height;
if (innerPage.Height * widthRatio <= innerPageHeight)
{
innerPage.Width *= widthRatio;
innerPage.Height *= widthRatio;
innerPage.RenderTransform = new ScaleTransform(widthRatio, widthRatio);
}
else
{
innerPage.Width *= heightRatio;
innerPage.Height *= heightRatio;
innerPage.RenderTransform = new ScaleTransform(heightRatio, heightRatio);
}
innerGrid.Children.Add(innerPage);
outergrid.Children.Add(innerGrid);
currentPageCount++;
}
}
outerPage.Children.Add(outergrid);
doc.Pages.Add(new PageContent { Child = outerPage });
}
return doc;
}
}
}
И вы можете использовать его так:
PreviewHelper.MultiPagesPerSheetHelper multiPagesPerSheetHelper = new PreviewHelper.MultiPagesPerSheetHelper(PAGES_PER_SHEET_COUNT, ORGINAL_DOCUMENT, ORGINAL_DOCUMENT_SIZE, DOCUMENT_ORIENTATION);
FixedDocument newDocument = multiPagesPerSheetHelper.GetMultiPagesPerSheetDocument();
Это будет работать так: