none
FlowDocument打印时,向打印机发送文件太大,如何解决? RRS feed

  • 问题

  • hi,大家好!

    我在使用PrintDialog.PrintDocument打印FlowDocument出现下面问题:

    1.FlowDocument中文字才200左右(整个文档只有布局,没有图片,打印机是针式打印机),打印时向打印发现数据有30-50MB,发送每秒才5MB左右,整个发送到打印机都要5秒后才开始打印,太慢了,有什么方法可以解决?

    谢谢大家了,期待大家的建议。

    2014年12月1日 3:27

全部回复

  • 你好,

    根据其他帖子里面的一些解释:

    https://social.msdn.microsoft.com/forums/vstudio/en-US/a116da54-ce36-446a-8545-3f34e9b9038d/flowdocument-performance

    “It is intended to show large documents, especially in paginated view. In scroll view some features (like tables) may significantly delay the resize scenarios.”

    面对大型文件如果FlowDocument是分页视图的话效率会更高些。你的代码关于打印是怎么写的呢?

    MSDN上有一个Sample:

    https://code.msdn.microsoft.com/windowsdesktop/WPF-Printing-Overview-f28c541a

    如果你照他这么写结果如何?



    Barry
    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年12月2日 7:44
    版主
  • 谢谢你的答复。

    我看了你提供的代码,用法和我的差不多,不知道细节上有什么问题。

    我的代码在内网,只能手工输入,无法提供完整的代码

    下面是打印代码:

    public void Print(Receipt receipt)

    {

    //xmal文件转成FlowDocumentEx对象,FlowDocumentEx在FlowDocument只增加了一两个属性

    FlowDocumentEx flowDoc=GetFlowDoc(receipt);

    //FlowDocument上的数据都是通过数据绑定

    flowDoc.DataContext=receipt;

    //重新了下分页,加了个页眉

    DocumentPaginatorEx docPagintor=new DocumentPaginatorEx(flowDoc);

    //调用了下打印

    printDialog.PrintDocument(docPagintor)

    }

    内容用了一个TableEx,TableEx继承了Table,当有ItemSource改变时,就会往Table中增加行数,再往行中加ContentPresenter;ContentPresenter的ContentTemplate=S_Table_Item,Content=ItemSource中的一项数据,不知道这里会不会影响FlowDocument文件大小。

    FlowDocumentEx:

    <FlowDocumentEx>

    <Table>
            <TableRowGroup>
                <TableRow>
                    <TableCell>
                        <my:TableEx DataTemplate="{DynamicResource S_Table_Item }"  ItemSource="{Binding Detail}" />
                    </TableCell>
                </TableRow>
            </TableRowGroup>
        </Table>

    </FlowDocumentEx>

     DataTemplate:

    <DataTemplate x:key ="S_Table_Item">

    <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="70" />
                                                <ColumnDefinition Width="140" />
                                                <ColumnDefinition Width="35" />
                                                <ColumnDefinition Width="40" />
                                                <ColumnDefinition />
                                            </Grid.ColumnDefinitions>
                                            <TextBlock Text="{Binding Name}" Grid.Column="0" Style="{DynamicResource S_TextBlock_10}" />
                                            <TextBlock Text="{Binding Name}" Grid.Column="1" Style="{DynamicResource S_TextBlock_10}" />
                                            <TextBlock Text="{Binding Name}" Grid.Column="2" Style="{DynamicResource S_TextBlock_10}" HorizontalAlignment="Center" />
                                            <TextBlock Text="{Binding Name}" Grid.Column="3" Style="{DynamicResource S_TextBlock_10}" HorizontalAlignment="Right" />
                                            <TextBlock Text="{Binding Name}" Grid.Column="4" Style="{DynamicResource S_TextBlock_10}" HorizontalAlignment="Right" />
                                        </Grid>

    </DataTemplate >

    2014年12月3日 2:12
  • 没关系,关键代码已经有了,其实这块我也还没有手动去试过,所以还不是很确定,我看你的代码似乎没什么问题,也确实是分页模式,但是我没找到DocumentPaginatorEx这个类,可能咱们的.NET版本有区别。

    你要不试试用这个代码:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        PrintDialog pd = new PrintDialog();
        if (pd.ShowDialog() != true) return;
    
    
        flowDocument.PageHeight = pd.PrintableAreaHeight;
        flowDocument.PageWidth = pd.PrintableAreaWidth;
    
    
        IDocumentPaginatorSource idocument = flowDocument as IDocumentPaginatorSource;
    
    
        pd.PrintDocument(idocument.DocumentPaginator, "Printing Flow Document...");

    使用的是这个接口 http://msdn.microsoft.com/en-us/library/system.windows.documents.idocumentpaginatorsource(v=vs.110).aspx 看看会不会好一些,还不行的话我得想办法找东西来测一下了。

    Regards,



    Barry
    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年12月3日 10:06
    版主
  • 谢谢你的回复。

    看了你的代码,和我也差不多,只是我封装了下,我提供代码不太完善,你也不好分析。

    DocumentPaginatorEx 其实是继承了DocumentPaginator

    //flowDoc 是FlowDocumentEx的实例(FlowDocumentEx继承FlowDocument,增加Height,Width)

    DocumentPaginatorEx docPagintor=new DocumentPaginatorEx(flowDoc);

    //docPagintor等于idocument.DocumentPaginator,我也不知道为什么,列表数据1,2行,发送打印机数据20M,10-15行60M,太慢了,也就打打票据,是不是这种方式不适合打票据。

    printDialog.PrintDocument(docPagintor)

    DocumentPaginEx的代码如下,大概就这样,可能属性不完善。

    public class DocumentPaginEx:DocumentPaginator
        {
            public double PageHeight;
            public double PageWidth;
            FlowDocumentEx flowDoc;
            public DocumentPaginEx(FlowDocumentEx flowDoc)
            {
                this.flowDoc = flowDoc;
                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
                {
                    PageHeight = flowDoc.Width / 2.54 * g.DpiY;
                    PageWidth = flowDoc.Height / 2.54 * g.DpiX;
                    flowDoc.PageHeight = PageHeight;
                    flowDoc.PageWidth = PageWidth;
                }
            }

            public override DocumentPage GetPage(int pageNumber)
            {
                DocumentPage page = Source.DocumentPaginator.GetPage(pageNumber);
                ContainerVisual visual = new ContainerVisual();
                visual.Children.Add(page.Visual);

                DataTemplate datatemplate = this.flowDoc.HeaderTempate as DataTemplate;
                DrawingVisual headerVisual = new DrawingVisual();
                ContentPresenter headerContent = new ContentPresenter();
                headerContent.ContentTemplate = datatemplate;
                headerContent.Content = this.flowDoc.DataContext;
                headerContent.Width = this.flowDoc.HeaderHeight;

                Rect bleedBox = new Rect() {
                    X=page.ContentBox.Left,
                    Y=this.flowDoc.PagePadding.Top,

                    Width=page.ContentBox.Width,
                    Height=headerContent.Height
                };

                using (DrawingContext dc = headerVisual.RenderOpen())
                {
                    dc.DrawRectangle(new VisualBrush(headerVisual) { Stretch=Stretch.None,AlignmentX=AlignmentX.Left,AlignmentY=AlignmentY.Top});
                    dc.Close();
                }
                visual.Children.Add(headerVisual);
                return new DocumentPage(visual,page.Size,bleedBox,page.ContentBox);
            }

            public override bool IsPageCountValid
            {
                get
                {
                    return Source.DocumentPaginator.IsPageCountValid;
                }
            }

            public override int PageCount
            {
                get { return Source.DocumentPaginator.PageCount; }
            }

            public override System.Windows.Size PageSize
            {
                get
                {
                    return Source.DocumentPaginator.PageSize;
                }
                set
                {
                    Source.DocumentPaginator.PageSize = value;
                }
            }

            public override IDocumentPaginatorSource Source
            {
                get { return flowDoc as IDocumentPaginatorSource; }
            }
        }

    }

    2014年12月3日 10:41