Как добавить несколько страниц на фиксированный документ в XPS?
Мое требование состоит в том, чтобы создать документ xps, который имеет 10 страниц (скажем). Я использую следующий код для создания документа XPS. Пожалуйста, взгляните.
// Create the new document
XpsDocument xd = new XpsDocument("D:\\9780545325653.xps", FileAccess.ReadWrite);
IXpsFixedDocumentSequenceWriter xdSW = xd.AddFixedDocumentSequence();
IXpsFixedDocumentWriter xdW = xdSW.AddFixedDocument();
IXpsFixedPageWriter xpW = xdW.AddFixedPage();
fontURI = AddFontResourceToFixedPage(xpW, @"D:\arial.ttf");
image = AddJpegImageResourceToFixedPage(xpW, @"D:\Single content\20_1.jpg");
StringBuilder pageContents = new StringBuilder();
pageContents.Append(ReadFile(@"D:\Single content\20.fpage\20.fpage", i));
xmlWriter = xpW.XmlWriter;
xmlWriter.WriteRaw(pageContents.ToString());
}
xmlWriter.Close();
xpW.Commit();
// Commit the fixed document
xdW.Commit();
// Commite the fixed document sequence writer
xdSW.Commit();
// Commit the XPS document itself
xd.Close();
}
private static string AddFontResourceToFixedPage(IXpsFixedPageWriter pageWriter, String fontFileName)
{
string fontUri = "";
using (XpsFont font = pageWriter.AddFont(false))
{
using (Stream dstFontStream = font.GetStream())
using (Stream srcFontStream = File.OpenRead(fontFileName))
{
CopyStream(srcFontStream, dstFontStream);
// commit font resource to the package file
font.Commit();
}
fontUri = font.Uri.ToString();
}
return fontUri;
}
private static Int32 CopyStream(Stream srcStream, Stream dstStream)
{
const int size = 64 * 1024; // copy using 64K buffers
byte[] localBuffer = new byte[size];
int bytesRead;
Int32 bytesMoved = 0;
// reset stream pointers
srcStream.Seek(0, SeekOrigin.Begin);
dstStream.Seek(0, SeekOrigin.Begin);
// stream position is advanced automatically by stream object
while ((bytesRead = srcStream.Read(localBuffer, 0, size)) > 0)
{
dstStream.Write(localBuffer, 0, bytesRead);
bytesMoved += bytesRead;
}
return bytesMoved;
}
private static string ReadFile(string filePath,int i)
{
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite);
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(fs))
{
String line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
}
string allines = sb.ToString();
//allines = allines.Replace("FontUri=\"/Resources/f7728e4c-2606-4fcb-b963-d2d3f52b013b.odttf\"", "FontUri=\"" + fontURI + "\" ");
//XmlReader xmlReader = XmlReader.Create(fs, new XmlReaderSettings() { IgnoreComments = true });
XMLSerializer serializer = new XMLSerializer();
FixedPage fp = (FixedPage)serializer.DeSerialize(allines, typeof(FixedPage));
foreach (Glyphs glyph in fp.lstGlyphs)
{
glyph.FontUri = fontURI;
}
fp.Path.PathFill.ImageBrush.ImageSource = image;
fs.Close();
string fpageString = serializer.Serialize(fp);
return fpageString;
}
private static string AddJpegImageResourceToFixedPage(IXpsFixedPageWriter pageWriter, String imgFileName)
{
XpsImage image = pageWriter.AddImage("image/jpeg");
using (Stream dstImageStream = image.GetStream())
using (Stream srcImageStream = File.OpenRead(imgFileName))
{
CopyStream(srcImageStream, dstImageStream); // commit image resource to the package file
//image.Commit();
}
return image.Uri.ToString();
}
Если вы видите это, я бы передал одно изображение и одну страницу для создания документа xps. Я хочу передать несколько списков fpages и список изображений, чтобы создать документ xps, который имеет несколько страниц..?
1 ответ
Вы делаете это самым мучительным образом из всех возможных. Я бы предложил пойти по маршруту ленивого человека.
Поймите, что XpsDocument это просто оболочка на FixedDocumentSequence
, который содержит ноль или более FixedDocuments
, который содержит ноль или более FixedPages
, Все эти типы можно создавать, манипулировать и комбинировать без написания XML.
Все, что вам действительно нужно, это создать FixedPage с любым содержимым, в котором вы нуждаетесь. Вот пример:
static FixedPage CreateFixedPage(Uri imageSource)
{
FixedPage fp = new FixedPage();
fp.Width = 320;
fp.Height = 240;
Grid g = new Grid();
g.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
g.VerticalAlignment = System.Windows.VerticalAlignment.Center;
fp.Children.Add(g);
Image img = new Image
{
UriSource = imageSource,
};
g.Children.Add(image);
return fp;
}
Это все WPF. Я создаю FixedPage, корнем которой является Grid, который содержит изображение, загруженное из данного Uri. Изображение будет растянуто, чтобы заполнить доступное пространство сетки. Или вы можете делать все, что хотите. Создайте шаблон как UserControl, отправьте его текст, чтобы разместить внутри себя, что угодно.
Далее вам просто нужно добавить несколько фиксированных страниц в XpsDocument
, Это невероятно сложно, поэтому читайте внимательно:
public void WriteAllPages(XpsDocument document, IEnumerable<FixedPage> pages)
{
var writer = XpsDocument.CreateXpsDocumentWriter(document);
foreach(var page in pages)
writer.Write(page);
}
И это все, что вам нужно сделать. Создайте свои страницы, добавьте их в свой документ. Готово.