【问题标题】:Report Viewer - normal mode not same as print preview mode报告查看器 - 正常模式与打印预览模式不同
【发布时间】:2018-10-26 13:07:42
【问题描述】:

我正在为我的报告使用 ReportViewer 控件,并且用户需要搜索功能,Reportviewer 已经内置了该功能,并且还打印了 Microsoft 未包含的“当前页面”功能,因此我自己编写了它...问题是在普通模式下,所有链接的数据都合并在同一页面中,并且在打印预览页面中有分页符。这会导致“正常”与“打印预览”模式下的页码不同,因为 ReportViewer 在切换这些模式时呈现方式不同。所以当我尝试打印当前页面时,例如正常模式下的“19” 我将在打印预览模式下打印出第 19 页,这与您在屏幕上看到的不同。

我能做些什么 - 以正常模式会破坏页面的方式更改 .rdlc 项目,就像打印预览一样?或者获取我在屏幕上看到的内容的流图像并将其打印出来?....任何帮助表示感谢,我正在努力寻找解决这个问题的方法,但到目前为止还没有成功...

编辑:我在 ReportViewer 中打印当前页面的课程。它可能对某人有帮助,它适用于打印预览模式,但不适用于普通模式如果您的链接数据太大以至于页面有分页符 - 因为用于打印当前页面的流图像实际上复制了您在 .rdlc 报告项目中设置的内容- 在我的情况下,A4 纸张尺寸:

class TiskanjeTrenutneStrani : PrintDocument
{
    private PageSettings nastavitve_strani;
    private int stran_za_tiskanje;
    private List<Stream> strani_reporta = new List<Stream>();

    public TiskanjeTrenutneStrani(LocalReport localReport, int stran)
        : this((Report)localReport)
    {
        //Set page for printing
        stran_za_tiskanje = stran-1;
        RenderirajStraniIzpisa(localReport);
    }

    private TiskanjeTrenutneStrani(Report report)
    {
        //Set page as defined in report project
        ReportPageSettings nastavitve_Report_Strani = report.GetDefaultPageSettings();
        var  nastavitve_strani = new PageSettings
        {
            PaperSize = nastavitve_Report_Strani.PaperSize,
            Margins = nastavitve_Report_Strani.Margins
        };
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);

        if (disposing)
        {
            foreach (Stream s in strani_reporta)
            {
                s.Dispose();
            }

            strani_reporta.Clear();
        }
    }

    protected override void OnPrintPage(PrintPageEventArgs e)
    {
        base.OnPrintPage(e);

        Stream TiskanaStran = strani_reporta[stran_za_tiskanje];
        TiskanaStran.Position = 0;

        // Load each page into a Metafile to draw it.
        using (Metafile pageMetaFile = new Metafile(TiskanaStran))
        {
            Rectangle rc = new Rectangle(
                    e.PageBounds.Left - (int)e.PageSettings.HardMarginX,
                    e.PageBounds.Top - (int)e.PageSettings.HardMarginY,
                    e.PageBounds.Width,
                    e.PageBounds.Height);


            e.Graphics.FillRectangle(Brushes.White, rc);

            e.Graphics.DrawImage(pageMetaFile, rc);

        }
    }

    protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e)
    {
        e.PageSettings = (PageSettings)nastavitve_strani.Clone();
    }

    private void RenderirajStraniIzpisa(LocalReport localReport)
    {
        string deviceInfo = CreateEMFDeviceInfo();

        localReport.Render("IMAGE", deviceInfo, LocalReportCreateStreamCallback, out Warning[] warnings);
    }

    private Stream LocalReportCreateStreamCallback(string name, string extension, Encoding encoding, string mimeType, bool willSeek)
    {
        MemoryStream stream = new MemoryStream();
        strani_reporta.Add(stream);
        return stream;
    }

    private string CreateEMFDeviceInfo()
    {
        PaperSize velikost_papirja = nastavitve_strani.PaperSize;
        Margins margins = nastavitve_strani.Margins;

        // The device info string defines the page range to print as well as the size of the page.
        // A start and end page of 0 means generate all pages.
        return
            string.Format(CultureInfo.InvariantCulture,
            "<DeviceInfo><OutputFormat>emf</OutputFormat><StartPage>0</StartPage><EndPage>0</EndPage><MarginTop>{0}</MarginTop><MarginLeft>{1}</MarginLeft><MarginRight>{2}</MarginRight><MarginBottom>{3}</MarginBottom><PageHeight>{4}</PageHeight><PageWidth>{5}</PageWidth></DeviceInfo>",
        ToInches(margins.Top),
            ToInches(margins.Left),
            ToInches(margins.Right),
            ToInches(margins.Bottom),
            ToInches(velikost_papirja.Height),
            ToInches(velikost_papirja.Width));
    }

    private static string ToInches(int hundrethsOfInch)
    {
        double inches = hundrethsOfInch / 100.0;
        return inches.ToString(CultureInfo.InvariantCulture) + "in";
    }

}

用法:

  TiskanjeTrenutneStrani tiskaj_stran = new 
  TiskanjeTrenutneStrani(this.LocalReport, this.CurrentPage);
  tiskaj_stran.Print(); // And It prints current page - unfortunally not what you see on screen If in normal mode

【问题讨论】:

  • 如果您能提供minimal reproducible example,那就太好了。
  • @mjwills,这是我打印当前页面的代码 - 如果有帮助的话。

标签: c# reportviewer


【解决方案1】:

你可以试试这个。

DeviceInfo 中的StartPageEndpage 设置为stran_za_tiskanje。

string.Format(CultureInfo.InvariantCulture,
            "<DeviceInfo><OutputFormat>emf</OutputFormat><StartPage>{6}</StartPage><EndPage>{6}</EndPage><MarginTop>{0}</MarginTop><MarginLeft>{1}</MarginLeft><MarginRight>{2}</MarginRight><MarginBottom>{3}</MarginBottom><PageHeight>{4}</PageHeight><PageWidth>{5}</PageWidth></DeviceInfo>",
        ToInches(margins.Top),
            ToInches(margins.Left),
            ToInches(margins.Right),
            ToInches(margins.Bottom),
            ToInches(velikost_papirja.Height),
            ToInches(velikost_papirja.Width),
            stran_za_tiskanje);

由于您指定了一个页面,因此您应该只有一项可以抓取。

Stream TiskanaStran = strani_reporta[0];

【讨论】:

  • 感谢您的回复,但这并不能解决它。我猜你不太明白我的意思——stream 会复制一份报告,正如你在打印预览中看到的那样,如果你有分页符,那就是分页符。但是,当您处于正常模式时,所有带有分页符的页面都会合并到一个页面中,即不同的渲染,与更快的“搜索”功能有关。因此,当我在正常模式下打印第 6 页时,我将从打印预览模式中获得第 6 页的副本 - 如果报告中的某些先前页面已经有分页符,那可能与您在屏幕上看到的不同。
  • 我相信解决方案是以某种方式计算您当前在正常模式下搜索的页面的流图像的页码,以判断应该从流中打印哪个页面......或创建不同类型的流式传输并仅打印您在屏幕上看到的内容,而不管报告项目页面设置如何......
猜你喜欢
  • 1970-01-01
  • 2010-10-07
  • 2020-12-27
  • 1970-01-01
  • 2014-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多