Как добавить несколько кадров в фиксированный документ в 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();

    }

Если вы это видите, я бы передал одно изображение и одну fpage для создания документа XPS. Я хочу передать список нескольких страниц и список изображений, чтобы создать документ XPS с несколькими страницами..?


person Shafiq Abbas    schedule 17.06.2013    source источник


Ответы (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);
}

И это все, что вам нужно сделать. Создайте свои страницы, добавьте их в свой документ. Готово.

person Community    schedule 17.06.2013
comment
+1 за экономию моего времени, отрицая мучительно сложные вещи :) - person WiiMaxx; 05.07.2013
comment
Writer.Write(page) приводит к тому, что Document Writer завершает запись и больше не может обрабатывать запросы на запись. - person wischi; 24.10.2013
comment
@wischi: Нет. Создайте минимальный репро в прототипе и посмотрите, произойдет ли это снова. Если это так, задайте вопрос, используя код из реплики. Если нет, вы делаете что-то не так с писателем, например сбрасываете, закрываете или удаляете. - person ; 24.10.2013
comment
@Will, вы можете вызвать XpsDocumentWriter.Write() только один раз. Виши не делает ничего плохого. - person Cory Nelson; 16.02.2015