C#:是否有一种方法可以将窗口保存为PDF?

3
我正在使用C#生成一个带有大量结果的窗口(滚动条):Window ResultsWindow = new Window();
在底部有两个按钮,即取消和打印。第一个按钮能够正常工作。然而,打印按钮应该将窗口转换为PDF文件,或者提供一步操作,让用户之后可以保存文件。
    private void Print_click(object sender, RoutedEventArgs e)
    {   
        //add code to print the whole window??
        ResultsWindow.Close();            
    }

你们当中有人知道这个怎么能够工作吗?

最好的问候


这个窗口里到底有什么内容?也许你真正想要保存的是显示的数据,而不是窗口本身?在.NET中有一些库可以生成PDF文件,并允许你将数据插入其中。然而,如果你确实想要一个屏幕截图,那就是另外一回事了(尽管你提到了滚动条,所以屏幕截图可能没有太大用处?) - undefined
嗨,是的,里面的数据带有相应的颜色和格式。你指的是哪些库? - undefined
请注意,如果您使用了颜色和格式设置,那是界面的一部分,而不是数据的一部分。因此,要创建一个等效的PDF文件而不是截屏,您可能需要类似的逻辑来将数据在PDF文档中的格式与屏幕输出相匹配。另外,您没有说明这是WinForms、WPF还是其他什么? - undefined
我假设这是WinForms...这是你的代码,你怎么不知道它是哪种项目?看一下项目属性,应该能告诉你。 - undefined
可以截取一个窗口的屏幕截图吗,比如它的顶部,然后使用滚动条并截取底部的内容?也许可以,但结果可能会很糟糕。 - undefined
显示剩余4条评论
2个回答

3

我不是特别漂亮(或经过测试),但使用了来自答案的信息。

这将创建一个窗口的XPS文件,并将其转换为PDF。

using System.IO;
using System.IO.Packaging;
using System.Windows;
using System.Windows.Xps;
using System.Windows.Xps.Packaging;

namespace WpfApp8
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            /*
             *  Convert WPF -> XPS -> PDF
             */
            MemoryStream lMemoryStream = new MemoryStream();
            Package package = Package.Open(lMemoryStream, FileMode.Create);
            XpsDocument doc = new XpsDocument(package);
            XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
            
            // This is your window
            writer.Write(this);

            doc.Close();
            package.Close();
            
            // Convert 
            MemoryStream outStream = new MemoryStream();
            PdfSharp.Xps.XpsConverter.Convert(lMemoryStream, outStream, false);

            // Write pdf file
            FileStream fileStream = new FileStream("C:\\test.pdf", FileMode.Create);
            outStream.CopyTo(fileStream);

            // Clean up
            outStream.Flush();
            outStream.Close();
            fileStream.Flush();
            fileStream.Close();
        }
    }
}

它使用PdfSharp NuGet包和kenjiuno.PdfSharp.Xps包来为PdfSharp添加XPS支持。

References


1
@shrox1740我已更新答案,包括我的参考文献和完整代码示例。你正在使用什么版本的.NET/C#? - undefined
.NET版本是4.5,如果你指的是这个的话。看起来我已经添加了你列出的所有引用。 - undefined
如果你没有说你已经添加了所有的引用,我会认为ReachFramework dll不存在。这似乎是在线上最常见的原因。我猜你已经清理并重新构建了你的解决方案? - undefined
在网上搜索一下。你可以尝试一种方法,使用PrintDialog的PrintVisual方法,但这样直接打印到用户的打印机上,没有进行PDF转换。恐怕这不是我的专长领域。 - undefined
这个解决方案对我来说几乎完美。唯一需要明确安装的 NuGet 包是 nuget.org/packages/kenjiuno.PdfSharp.Xps。需要注意的是,最终的 PDF 页面将在右侧和底部有一个白色边距,这相当不理想,但你可以通过将 Window.WindowStyle 设置为 "None" 和 Window.ResizeMode 设置为 "NoResize" 来去除它们。(@shrox1740) - undefined
显示剩余2条评论

0
假设你正在使用WPF,这是我实现类似功能的方法:
private void Button_Click(object sender, RoutedEventArgs e)
    {
        var wasMax = this.WindowState == WindowState.Maximized;
        UBlattWindow.WindowState = WindowState.Normal;
        var initHeight = UBlattWindow.ActualHeight;
        var initWidth = UBlattWindow.ActualWidth;
        UBlattWindow.Width = 955;
        UBlattWindow.Height = UBlattWindow.Height + (ScrollerContent.ActualHeight - Scroller.ActualHeight) + 20;

        Print(printGrid);
        UBlattWindow.Height = initHeight;
        UBlattWindow.Width = initWidth;
        if (wasMax)
        {
            UBlattWindow.WindowState = WindowState.Maximized;
        }
    }

    private void Print(Visual v)
    {

        System.Windows.FrameworkElement e = v as System.Windows.FrameworkElement;
        if (e == null)
            return;

        PrintDialog pd = new PrintDialog();
        if (pd.ShowDialog() == true)
        {
            PageMediaSize pageSize = null;

            pageSize = new PageMediaSize(PageMediaSizeName.ISOA4);

            pd.PrintTicket.PageMediaSize = pageSize;

            //store original scale
            Transform originalScale = e.LayoutTransform;
            //get selected printer capabilities
            System.Printing.PrintCapabilities capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);

            //get scale of the print wrt to screen of WPF visual
            double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / e.ActualWidth, capabilities.PageImageableArea.ExtentHeight /
                           e.ActualHeight);

            //Transform the Visual to scale
            e.LayoutTransform = new ScaleTransform(scale, scale);

            //get the size of the printer page
            System.Windows.Size sz = new System.Windows.Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);

            //update the layout of the visual to the printer page size.
            e.Measure(sz);
            e.Arrange(new System.Windows.Rect(new System.Windows.Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));

            //now print the visual to printer to fit on the one page.
            pd.PrintVisual(v, "My Print");

            //apply the original transform.
            e.LayoutTransform = originalScale;
        }
    }

请注意,我使用Print方法来调整窗口的比例,以适应ISOA4格式。在打印之前,我还将窗口设置为固定的宽度和高度,并在打印后重新设置回原样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接