C# Visual studio 2015 community report viewer版本12使用c获取额外边距时出错#

C# Visual studio 2015 community report viewer版本12使用c获取额外边距时出错#,c#,sql-server,rdlc,C#,Sql Server,Rdlc,我正在使用Visual studio 2015 community report viewer版本12在我的c#项目中显示rdlc报告。 这是一份普通的A4纸报告 它适用于客户端PC上的windows xp、vista和win 7,但当相同的应用程序安装在64位windows 10上时,我将面临如下问题 正如你们在上图中看到的那个样,不必要的边距来自右边和底端,字体大小也减小了。但当我将报告导出到PDF时,生成的PDF和我设计的报告一样,并没有问题 我尝试了什么: 我从安装MICROSOFT

我正在使用Visual studio 2015 community report viewer版本12在我的c#项目中显示rdlc报告。 这是一份普通的A4纸报告

它适用于客户端PC上的windows xp、vista和win 7,但当相同的应用程序安装在64位windows 10上时,我将面临如下问题

正如你们在上图中看到的那个样,不必要的边距来自右边和底端,字体大小也减小了。但当我将报告导出到PDF时,生成的PDF和我设计的报告一样,并没有问题

我尝试了什么:

  • 我从安装MICROSOFT®REPORT VIEWER 2015运行时
  • 已安装Microsoft®SQL Server®2014功能包(SQL的系统CLR类型 服务器(2014)
  • 尝试使用以下代码将RDLC直接导出到打印机
  • 打印类代码

    public static class _cWainfoPrintReport
        {
            private static int m_currentPageIndex;
            private static IList<Stream> m_streams;
            public static Stream CreateStream(string name,
            string fileNameExtension, Encoding encoding,
            string mimeType, bool willSeek)
            {
                Stream stream = new MemoryStream();
                m_streams.Add(stream);
                return stream;
            }
            public static void _mExport(LocalReport report, bool print = true, double _pageWightInches = 8.27, double _pageHeightInches = 11.69, double _MarginTopInches = 0.025, double _MarginLeftInches = 0.025, double _MarginRightInches = 0.025, double _MarginBottomInches = 0.025)
            {
                string deviceInfo =
                @"<DeviceInfo> <OutputFormat>EMF</OutputFormat> <PageWidth>" + _pageWightInches + "in</PageWidth> <PageHeight>" + _pageHeightInches + "in</PageHeight> <MarginTop>" + _MarginTopInches + "in</MarginTop> <MarginLeft>" + _MarginLeftInches + "in</MarginLeft> <MarginRight>" + _MarginRightInches + "in</MarginRight> <MarginBottom>" + _MarginBottomInches + "in</MarginBottom> </DeviceInfo>";
                Warning[] warnings;
                m_streams = new List<Stream>();
                report.Render("Image", deviceInfo, CreateStream,
                out warnings);
                foreach (Stream stream in m_streams)
                    stream.Position = 0;
                if (print)
                {
                    _mPrint(_pageWightInches, _pageHeightInches, _MarginTopInches, _MarginLeftInches, _MarginRightInches, _MarginBottomInches);
                }
                report.ReleaseSandboxAppDomain();
            }
            // Handler for PrintPageEvents
            public static void _mPrintPage(object sender, PrintPageEventArgs ev)
            {
                Metafile pageImage = new
                Metafile(m_streams[m_currentPageIndex]);
                // Adjust rectangular area with printer margins.
                Rectangle adjustedRect = new Rectangle(
                ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
                ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
                ev.PageBounds.Width,
                ev.PageBounds.Height);
                // Draw a white background for the report
                ev.Graphics.FillRectangle(Brushes.White, adjustedRect);
                // Draw the report content
                ev.Graphics.DrawImage(pageImage, adjustedRect);
                // Prepare for the next page. Make sure we haven't hit the end.
                m_currentPageIndex++;
                ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
            }
            public static PaperSize CalculatePaperSize(double WidthInCentimeters, double HeightInCentimetres)
            {
                int Width = int.Parse((Math.Round((WidthInCentimeters * 0.393701) * 100, 0, MidpointRounding.AwayFromZero)).ToString());
                int Height = int.Parse((Math.Round((HeightInCentimetres * 0.393701) * 100, 0, MidpointRounding.AwayFromZero)).ToString());
    
                PaperSize NewSize = new PaperSize();
                NewSize.RawKind = (int)PaperKind.Custom;
                NewSize.Width = Width;
                NewSize.Height = Height;
                NewSize.PaperName = "Letter";
    
                return NewSize;
    
            }
            public static void _mPrint(double _pageWightInches = 8.27, double _pageHeightInches = 11.69, double _MarginTopInches = 0.025, double _MarginLeftInches = 0.025, double _MarginRightInches = 0.025, double _MarginBottomInches = 0.025)
            {
                if (m_streams == null || m_streams.Count == 0)
                    throw new Exception("Error: no stream to print.");
                PrintDocument printDoc = new PrintDocument();
    
                PaperSize RequiredPaperSize = CalculatePaperSize(_pageWightInches * 2.54, _pageHeightInches * 2.54);
                bool FoundMatchingPaperSize = false;
                for (int index = 0; index < printDoc.PrinterSettings.PaperSizes.Count; index++)
                {
                    if (printDoc.PrinterSettings.PaperSizes[index].Height == RequiredPaperSize.Height && printDoc.PrinterSettings.PaperSizes[index].Width == RequiredPaperSize.Width)
                    {
                        printDoc.PrinterSettings.DefaultPageSettings.PaperSize = printDoc.PrinterSettings.PaperSizes[index];
                        printDoc.DefaultPageSettings.PaperSize = printDoc.PrinterSettings.PaperSizes[index];
                        FoundMatchingPaperSize = true;
                        break;
                    }
                }
    
    
                if (!printDoc.PrinterSettings.IsValid)
                {
                    throw new Exception("Error: cannot find the default printer.");
                }
                else
                {
    
                    printDoc.PrintPage += new PrintPageEventHandler(_mPrintPage);
                    m_currentPageIndex = 0;
                    printDoc.Print();
                }
            }
            public static void _mPrintToPrinter(this LocalReport report)
            {
                _mExport(report);
            }
            public static void _mDisposePrint()
            {
                if (m_streams != null)
                {
                    foreach (Stream stream in m_streams)
                        stream.Close();
                    m_streams = null;
                }
            }
        }
    
    但它也和上面描述的一样

    同一应用程序正在我的带有Windows 10 64位的电脑上运行,但在带有Windows 10 64位的客户端电脑上部署后无法工作

    在客户端PC.Net 4.0框架上,安装了SQL Server 2008、Windows 10 64位


    如何解决此问题。

    我认为此问题与安装的任何工具无关,尤其是与Windows 10 64位无关

    相反,正如jdweng&Reza Aghaei所提到的,这是一个与新闻部有关的问题。更具体地说,高DPI设备

    不确定您是否注意到,但您上载的两个图像的像素不同,并且像素较低的图像显示报告的正确呈现。这可以说支持了由于高DPI导致的缩放问题

    现在,这方面有很多文章、帖子和问题。但在微软支持门户网站上,似乎几乎没有为这种行为提供可能的解决方案(是的,复数形式)和解决办法(再次,复数形式)

    你可以在这里找到这篇文章:

    我相信,我在下面引用的解决方法暂时应该对您有所帮助

    更改应用程序属性

    public static class _cWainfoPrintReport
        {
            private static int m_currentPageIndex;
            private static IList<Stream> m_streams;
            public static Stream CreateStream(string name,
            string fileNameExtension, Encoding encoding,
            string mimeType, bool willSeek)
            {
                Stream stream = new MemoryStream();
                m_streams.Add(stream);
                return stream;
            }
            public static void _mExport(LocalReport report, bool print = true, double _pageWightInches = 8.27, double _pageHeightInches = 11.69, double _MarginTopInches = 0.025, double _MarginLeftInches = 0.025, double _MarginRightInches = 0.025, double _MarginBottomInches = 0.025)
            {
                string deviceInfo =
                @"<DeviceInfo> <OutputFormat>EMF</OutputFormat> <PageWidth>" + _pageWightInches + "in</PageWidth> <PageHeight>" + _pageHeightInches + "in</PageHeight> <MarginTop>" + _MarginTopInches + "in</MarginTop> <MarginLeft>" + _MarginLeftInches + "in</MarginLeft> <MarginRight>" + _MarginRightInches + "in</MarginRight> <MarginBottom>" + _MarginBottomInches + "in</MarginBottom> </DeviceInfo>";
                Warning[] warnings;
                m_streams = new List<Stream>();
                report.Render("Image", deviceInfo, CreateStream,
                out warnings);
                foreach (Stream stream in m_streams)
                    stream.Position = 0;
                if (print)
                {
                    _mPrint(_pageWightInches, _pageHeightInches, _MarginTopInches, _MarginLeftInches, _MarginRightInches, _MarginBottomInches);
                }
                report.ReleaseSandboxAppDomain();
            }
            // Handler for PrintPageEvents
            public static void _mPrintPage(object sender, PrintPageEventArgs ev)
            {
                Metafile pageImage = new
                Metafile(m_streams[m_currentPageIndex]);
                // Adjust rectangular area with printer margins.
                Rectangle adjustedRect = new Rectangle(
                ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
                ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
                ev.PageBounds.Width,
                ev.PageBounds.Height);
                // Draw a white background for the report
                ev.Graphics.FillRectangle(Brushes.White, adjustedRect);
                // Draw the report content
                ev.Graphics.DrawImage(pageImage, adjustedRect);
                // Prepare for the next page. Make sure we haven't hit the end.
                m_currentPageIndex++;
                ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
            }
            public static PaperSize CalculatePaperSize(double WidthInCentimeters, double HeightInCentimetres)
            {
                int Width = int.Parse((Math.Round((WidthInCentimeters * 0.393701) * 100, 0, MidpointRounding.AwayFromZero)).ToString());
                int Height = int.Parse((Math.Round((HeightInCentimetres * 0.393701) * 100, 0, MidpointRounding.AwayFromZero)).ToString());
    
                PaperSize NewSize = new PaperSize();
                NewSize.RawKind = (int)PaperKind.Custom;
                NewSize.Width = Width;
                NewSize.Height = Height;
                NewSize.PaperName = "Letter";
    
                return NewSize;
    
            }
            public static void _mPrint(double _pageWightInches = 8.27, double _pageHeightInches = 11.69, double _MarginTopInches = 0.025, double _MarginLeftInches = 0.025, double _MarginRightInches = 0.025, double _MarginBottomInches = 0.025)
            {
                if (m_streams == null || m_streams.Count == 0)
                    throw new Exception("Error: no stream to print.");
                PrintDocument printDoc = new PrintDocument();
    
                PaperSize RequiredPaperSize = CalculatePaperSize(_pageWightInches * 2.54, _pageHeightInches * 2.54);
                bool FoundMatchingPaperSize = false;
                for (int index = 0; index < printDoc.PrinterSettings.PaperSizes.Count; index++)
                {
                    if (printDoc.PrinterSettings.PaperSizes[index].Height == RequiredPaperSize.Height && printDoc.PrinterSettings.PaperSizes[index].Width == RequiredPaperSize.Width)
                    {
                        printDoc.PrinterSettings.DefaultPageSettings.PaperSize = printDoc.PrinterSettings.PaperSizes[index];
                        printDoc.DefaultPageSettings.PaperSize = printDoc.PrinterSettings.PaperSizes[index];
                        FoundMatchingPaperSize = true;
                        break;
                    }
                }
    
    
                if (!printDoc.PrinterSettings.IsValid)
                {
                    throw new Exception("Error: cannot find the default printer.");
                }
                else
                {
    
                    printDoc.PrintPage += new PrintPageEventHandler(_mPrintPage);
                    m_currentPageIndex = 0;
                    printDoc.Print();
                }
            }
            public static void _mPrintToPrinter(this LocalReport report)
            {
                _mExport(report);
            }
            public static void _mDisposePrint()
            {
                if (m_streams != null)
                {
                    foreach (Stream stream in m_streams)
                        stream.Close();
                    m_streams = null;
                }
            }
        }
    
    在资源管理器中或“开始”菜单上,右键单击应用程序名称,选择“属性”,选择“兼容性”选项卡,然后选中“禁用高DPI设置时的显示缩放”复选框

    注意: 在Windows 10版本1703和更高版本的Windows中,禁用高DPI设置上的显示缩放选项的文本将更改为覆盖高DPI缩放行为,缩放由:应用程序执行


    您应该禁用DPI Unaware并将应用程序设置为DPI aware(即使不是),以防止扩展

    在较新版本的Windows 10上,我发现了一种不同的解决方案:您可以让应用程序处于任何DPI感知状态,但可以让特定的窗口在不同的DPI感知状态下打开

    不幸的是,尽管如此,我仍然在寻找一个100%都能工作的州,但有两种选择似乎是很好的选择

    改变新闻部意识

                if (WindowsVersion.WindowsIs10_1809OrNewer) // this you can get yourself, need to look at build number
                {
                    // https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/DPIAwarenessPerWindow/client/DpiAwarenessContext.cpp
                    _prevHosting = WinAPI.SetThreadDpiHostingBehavior((IntPtr)WinAPI.DPI_HOSTING_BEHAVIOR.BEHAVIOR_MIXED);
    
                    _prevDPIContext = WinAPI.SetThreadDpiAwarenessContext((IntPtr)win10DPIAwareness); // WinAPI.ContextDPIAwareness.Context_UnawareGdiScaled);
                }
    
    然后您可以在此线程中打开新对话框,该对话框将包含ReportViewer

    以后再换

                        if (WindowsVersion.WindowsIs10_1809OrNewer)
                        {
                            WinAPI.SetThreadDpiAwarenessContext(_prevDPIContext);
                            WinAPI.SetThreadDpiHostingBehavior(_prevHosting);
                        }
    
    助手

        public static bool WindowsIs10_1809OrNewer
        {
            get { return WindowsIs10OrNewer && Environment.OSVersion.Version.Build >= 17763; }
        }
    
        public static bool WindowsIs10OrNewer
        {
            get { return Environment.OSVersion.Version >= new Version(10, 0); }
        }
    
        public enum DPI_HOSTING_BEHAVIOR
        {
            BEHAVIOR_INVALID = -1,
            BEHAVIOR_DEFAULT = 0,
            BEHAVIOR_MIXED = 1
        }
    
        public enum ContextDPIAwareness
        {
            Context_Unaware = -1,
            Context_SystemAware = -2,
            Context_PerMonitorAware = -3,
            Context_PerMonitorAwareV2 = -4,
            Context_UnawareGdiScaled = -5,
        }
    
    您可以尝试经常使用Context_UnawareGdiScaled(实际上可以正确缩放ReportViewer)或Context_PerMonitorAware来禁用缩放

    我在RDP会话中遇到了一些问题,如果您没有这些问题,可能您对这些选项没有意见

    此外,不幸的是,这只适用于较新的Windows10版本。由于这些更新不是可选的,可能大多数Windows 10用户将使用新版本,并且Windows 8不受欢迎,而所有其他Windows版本都不受支持,因此许多用户应该使用最新的Windows 10版本

    当然,这还远远不够完美


    顺便说一句,对于旧版本的Windows,我只是通过SetProcessdPiaware禁用了缩放功能,没有找到更好的方法。

    看起来是打印驱动程序导致了这个问题。我怀疑打印机有两个驱动程序,一个是PCL,一个是PS(Post脚本),使用了错误的驱动程序。@jdweng可能与打印驱动程序无关,它导致所有安装了64位windows 10的客户端PC,我的笔记本电脑(开发PC)也安装了64位Windows 10,但我没有面临这个问题。有趣的帖子:看起来微软解决了一个问题,破坏了很多用户应用程序:我读了很多书。看来这与“新闻部意识”有关。最好的文章出现在以下网页:@ImranAliKhan,我的荣幸!:)