保存为PDF

时间:2017-12-18 15:51:26

标签: wpf datagrid resolution pdfsharp gridlines

我正在使用DataGrid来表示WPF应用程序中的一些数据。在我正在使用PDFSharp保存将DataGrid转换为PDF的特定WPF窗口的功能中,我遇到的问题是,当以较小的查看百分比查看保存的PDF时,DataGrid GridLines不可见。 (参考附图,仅当PDF视图设置为139%时,GridLines才可见。但是,在较小的视图%中,某些网格线会被省略。)

  1. 66.7%
  2. 75%
  3. 100%
  4. 139%
  5. 这是PDF保存代码: -

    MemoryStream lMemoryStream = new MemoryStream();
    Package package = Package.Open(lMemoryStream, FileMode.Create);
    var doc = new System.Windows.Xps.Packaging.XpsDocument(package);
    XpsDocumentWriter writer = System.Windows.Xps.Packaging.XpsDocument.CreateXpsDocumentWriter(doc);
    
    VisualBrush sourceBrush = new VisualBrush(this);
    DrawingVisual drawingVisual = new DrawingVisual();
    
    using (var drawingContext = drawingVisual.RenderOpen())
    {
        drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(this.ActualWidth, this.ActualHeight)));
    }
    
    writer.Write(drawingVisual);
    doc.Close();
    package.Close();
    
    var pdfXpsDoc = PdfSharp.Xps.XpsModel.XpsDocument.Open(lMemoryStream);
    XpsConverter.Convert(pdfXpsDoc, sFileName, 0);
    

    我认为这与视觉效果的质量有关。然后我尝试了这个片段,我正在使用DrawImage以更高的分辨率制作视觉效果。这是片段: -

    MemoryStream lMemoryStream = new MemoryStream();
    Package package = Package.Open(lMemoryStream, FileMode.Create);
    var doc = new System.Windows.Xps.Packaging.XpsDocument(package);
    XpsDocumentWriter writer = System.Windows.Xps.Packaging.XpsDocument.CreateXpsDocumentWriter(doc);
    
    double dpiScale = 600.0 / 96.0;
    var renderBitmap = new RenderTargetBitmap(Convert.ToInt32(this.Width * dpiScale),
                           Convert.ToInt32(this.Height * dpiScale),
                           600.0,
                           600.0,
                           PixelFormats.Pbgra32);
    renderBitmap.Render(this);
    var visual = new DrawingVisual();
    using (var dc = visual.RenderOpen())
    {
        dc.DrawImage(renderBitmap, new Rect(0, 0, this.Width, this.Height));
    }                
    
    writer.Write(visual);
    doc.Close();
    package.Close();
    
    var pdfXpsDoc = PdfSharp.Xps.XpsModel.XpsDocument.Open(lMemoryStream);
    XpsConverter.Convert(pdfXpsDoc, _pdfFileName, 0);
    

    此片段正常工作,即使在较小的查看百分比中,网格线也可见,但它使我的应用程序停留在PDF保存操作,并且它还会抛出System.OutofMemoryException,并显示“内存不足以继续执行程序”。 “但是,应用程序不会崩溃。

    为了检查PDF查看器的行为,我在MS Word中生成了一个包含多行和多列的表,并将其另存为PDF。在这种情况下,即使在较小的观察百分比下,表格网格线也清晰可见。

    任何人都可以帮我吗?

2 个答案:

答案 0 :(得分:0)

我假设第一个代码段以矢量格式创建了一个表(您不提供允许验证此内容的PDF)。

第二个代码段尝试创建位图图像(栅格格式)。

无论哪种方式:对于矢量和光栅图像,它依赖于PDF查看器是否可见细线。 Adobe Reader有很多选项(例如"增强细线","平滑线艺术","平滑图像")会对实际显示产生影响 - 到在客户端计算机上设置,无需在PDF中设置。

我假设您使用MS Word进行的测试也创建了一个矢量格式的表格,但可能使用较粗的线条。所以这个测试没有任何证据。

答案 1 :(得分:0)

当缩小使用WPF创建的PDF时,我也遇到了网格线消失的问题。

问题在于,网格单元格中的TextBox对象具有默认的背景颜色(白色)和边框颜色(黑色),并且在缩小时它们都被绘制在同一位置。解决方案是将背景设置为“透明”,从而完全没有背景。

TextBox tx = new TextBox();
tx.Text = "X";
tx.SetValue(Grid.RowProperty, row);
tx.SetValue(Grid.ColumnProperty, col);
tx.BorderThickness = new Thickness(0.3, 0.3, 0, 0);
tx.BorderBrush = System.Windows.Media.Brushes.Black;
tx.Background = Brushes.Transparent;
grid.Children.Add(tx);

但是,如果您想在网格单元中有一些背景怎么办?然后的解决方案是将一个单独的Border对象添加到同一Grid单元中,并使用Zindex确保Border对象被绘制在其他内容的前面。

TextBox tx = new TextBox();
tx.Text = "X";
tx.SetValue(Grid.RowProperty, row);
tx.SetValue(Grid.ColumnProperty, col);
tx.BorderThickness = new Thickness(0);
tx.Background = Brushes.LightPink;
grid.Children.Add(tx);

Border ct = new Border();
ct.SetValue(Grid.RowProperty, row);
ct.SetValue(Grid.ColumnProperty, col);
ct.BorderThickness = new Thickness(0.3, 0.3, 0, 0);
ct.BorderBrush = System.Windows.Media.Brushes.Black;
ct.Background = Brushes.Transparent;
ct.HorizontalAlignment = HorizontalAlignment.Stretch;
ct.VerticalAlignment = VerticalAlignment.Stretch;
Grid.SetZIndex(ct, 100);
grid.Children.Add(ct);

此外,UseLayoutRounding必须设置为false(默认为false)。否则,厚度为0.5或更小的线将完全消失。