【问题标题】:How to add multiple fpages to fixed document in xps?如何在 xps 中将多个 fpage 添加到固定文档?
【发布时间】:2013-06-13 01:25:57
【问题描述】:

我的要求是创建有 10 页的 xps 文档(比如说)。我正在使用以下代码来创建 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 文档。我想传递多个 fpages 列表和图像列表来创建一个具有多个页面的 xps 文档..?

【问题讨论】:

    标签: c# .net wpf xps xpsdocument


    【解决方案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,其中包含从给定 Uri 加载的图像。图像将被拉伸以填充网格的可用空间。或者,你可以为所欲为。创建一个模板作为用户控件,将其发送文本以放置在其自身中,无论如何。

    接下来,您只需将一堆固定页面添加到XpsDocument。这非常难,所以请仔细阅读:

    public void WriteAllPages(XpsDocument document, IEnumerable<FixedPage> pages)
    {
    
        var writer = XpsDocument.CreateXpsDocumentWriter(document);
        foreach(var page in pages)
            writer.Write(page);
    }
    

    这就是您需要做的所有事情。创建您的页面,将它们添加到您的文档中。完成。

    【讨论】:

    • +1 通过否认极其困难的事情来节省我的时间 :)
    • writer.Write(page) 导致“文档编写器已完成写入,无法再处理任何写入请求。”
    • @wischi:不。在原型中创建一个最小重现,看看它是否会再次发生。如果是这样,请使用复制代码中的代码提出问题。如果不是,那么你就是在对 writer 做错事,例如冲洗或关闭或处置。
    • @Will,您只能调用 XpsDocumentWriter.Write() 一次。 wischi 没有做错任何事。
    猜你喜欢
    • 1970-01-01
    • 2011-07-16
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2021-01-02
    • 2019-06-16
    • 1970-01-01
    相关资源
    最近更新 更多