【问题标题】:wpf - how to print a whole page to pdf with PDFSharpwpf - 如何使用 PDFSharp 将整个页面打印为 pdf
【发布时间】:2016-04-27 21:08:42
【问题描述】:

所以我想知道如何使用 PDFSharp 将我的整个 WPF 页面打印到 PDF 文件中。 我已经看了几篇文章,但我似乎无法弄清楚。 我希望 pdf 看起来像这样:

我已经查看了有关绘制字符串的文章,以线条命名。但是对我来说,单独创建每条线、字符串和形状似乎是一个草率和糟糕的主意。

谁能帮我解决这个问题?

文章也将受到赞赏!

提前致谢

【问题讨论】:

    标签: c# wpf pdf pdf-generation


    【解决方案1】:

    我会说首先使用RenderTargetBitmap 将您的控件导出为图像,然后使用库将其导出为PDF。

    也许这个示例可能会有所帮助?

    http://www.techcognition.com/post/Create-PDF-File-From-WPF-Window-using-iTextsharp-1001

    有了这个library

    这是我成功使用的 Control to Image 类(我能够获得复杂 UI 控件的 PNG 快照,这意味着非常深的父子层次结构)

    source 是一个 WPF 控件容器(用户控件、网格、wahtever)。

    path 是 PNG 输出文件的完整路径 (C:\Temp\myImage.png)

    public class ControlToImageSnapshot
    {
        /// <summary>
        /// Conversion du controle en image PNG
        /// </summary>
        /// <param name="source">Contrôle à exporter</param>
        /// <param name="path">Destination de l'export</param>
        /// <param name="zoom">Taille désirée</param>
        public static void SnapShotPng(FrameworkElement source, string path, double zoom = 1.0)
        {
            try
            {
                var dir = Path.GetDirectoryName(path);
                if (dir != null && !Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
    
                RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)source.ActualWidth, (int)source.ActualHeight, 96, 96, PixelFormats.Pbgra32);
                VisualBrush sourceBrush = new VisualBrush(source);
    
    
                DrawingVisual drawingVisual = new DrawingVisual();
    
                DrawingContext drawingContext = drawingVisual.RenderOpen();
    
                using (drawingContext)
                {
    
                    drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(source.ActualWidth, source.ActualHeight)));
                }
                renderTarget.Render(drawingVisual);
    
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(renderTarget));
    
                using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
                {
                    encoder.Save(stream);
                }
    
                createPdfFromImage(path, @"C:\Temp\myfile.pdf");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        public static void createPdfFromImage(string imageFile, string pdfFile)
        {
            using (var ms = new MemoryStream())
            {
                var document = new iTextSharp.text.Document(iTextSharp.text.PageSize.LETTER.Rotate(), 0, 0, 0, 0);
                PdfWriter.GetInstance(document, new FileStream(pdfFile, FileMode.Create));
                iTextSharp.text.pdf.PdfWriter.GetInstance(document, ms).SetFullCompression();
                document.Open();
    
                FileStream fs = new FileStream(imageFile, FileMode.Open);
                var image = iTextSharp.text.Image.GetInstance(fs);
                image.ScaleToFit(document.PageSize.Width, document.PageSize.Height);
                document.Add(image);
                document.Close();
    
                //open pdf file
                Process.Start("explorer.exe", pdfFile);
            }
        }
    }
    

    【讨论】:

    • 意外的赞成票,对不起!该代码在项目中不起作用,尽管我有 iTextSharp,但我不太喜欢这个库。它在以下位置给出错误:SaveAsPng(GetImage(GridForm), sImagePath);
    • 那么问题来自于生成图像本身的方法,因为 PDF 功能对我来说工作得很好,而无需触及一行
    • 查看我编辑的答案,我已将快照控件的完整工作示例发布到 PNG,然后从 PNG 到 PDF
    • 那么,在这种情况下,您同时保存图像文件和pdf文件? @布鲁诺
    【解决方案2】:

    对于 pdfsharp 来说非常简单,你可以传入一个 pdf 图像和 pdf 的字节数组,我在处理 pdfsharp 中的图像时经常使用这个函数。

    相当不言自明

    打开pdf并将图像放入内存流

    获取 pdf 设置并选择要绘制的页面 我总是将 interpolate 设置为 false,如果您将图像中的阴影设置为 true,我处理的图像类型会得到更好的结果。

    那么你剩下要做的就是在 pdf 上绘制图像并作为内存流返回

        public static byte[] AddImageToPdf(byte[] pdf, byte[] img, double x, double y)
        {
            using (var msPdf = new MemoryStream(pdf))
            {
                using (var msImg = new MemoryStream(img))
                {
                    var image = Image.FromStream(msImg);
    
                    var document = PdfReader.Open(msPdf);
                    var page = document.Pages[0];
                    var gfx = XGraphics.FromPdfPage(page);
    
                    var ximg = XImage.FromGdiPlusImage(image);
                    ximg.Interpolate = false;
    
                    gfx.DrawImage(
                        ximg,
                        XUnit.FromCentimeter(x),
                        XUnit.FromCentimeter(y),
                        ximg.PixelWidth * 72 / ximg.HorizontalResolution,
                        ximg.PixelHeight * 72 / ximg.HorizontalResolution);
    
    
                    using (var msFinal = new MemoryStream())
                    {
                        document.Save(msFinal);
                        return msFinal.ToArray();
                    }
                }
            }
        }
    

    它为 pdf 中的第 1 页硬编码,如果您愿意,可以轻松扩展以传入页面,我把它留给自己作为练习,最后您会得到一个包含您的 pdf 的漂亮字节数组,没有文件需要触摸如果您将图像作为内存流从控件导入并传入,则地面航路。本主题中的另一个答案是获取控件图像的好方法。

    【讨论】:

      猜你喜欢
      • 2010-10-27
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 2013-08-01
      • 1970-01-01
      相关资源
      最近更新 更多