在Azure WebApp上将ReportViewer报告打印为PDF。获取一般GDI错误

时间:2018-05-16 12:12:48

标签: azure reportviewer gdi azure-web-app-service

我的代码将采用ReportViewer报告并通过PrintDialog进行打印。但是,当我将其移动到Azure WebApp时,我得到一般GDI错误。我一直在寻找解决方案,但我发现Azure阻止了大多数GDI呼叫。它正在摒弃下面的导出方法。任何建议的工作?

    private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
    {
        try
        {
            Stream stream = new MemoryStream();
            m_streams.Add(stream);
            return stream;
        }
        catch (Exception ex)
        {
            throw new Exception("CreateStream: " + ex.Message, ex.InnerException);
        }
    }

    public void Export(LocalReport report)
    {
        try
        {
            string deviceInfo =
              @"<DeviceInfo>
            <OutputFormat>EMF</OutputFormat>
            <PageWidth>8.5in</PageWidth>
            <PageHeight>11in</PageHeight>
            <MarginTop>0.25in</MarginTop>
            <MarginLeft>0.25in</MarginLeft>
            <MarginRight>0.25in</MarginRight>
            <MarginBottom>0.25in</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;
        }
        catch (Exception ex)
        {
            throw new Exception("Export: " + ex.Message, ex.InnerException);
        }

    }

2 个答案:

答案 0 :(得分:0)

所有Azure Web Apps都在称为沙箱的安全环境中运行。每个应用程序都在自己的沙箱中运行,将其执行与同一台机器上的其他实例隔离开来,并提供额外的安全性和隐私,否则将无法使用。

为了减少激进的攻击面积,沙盒可以防止几乎所有的Win32k.sys API被调用,这实际上意味着大多数User32 / GDI32系统调用都被阻止了。对于大多数应用程序而言,这不是问题,因为大多数Azure Web应用程序不需要访问Windows UI功能。但是,受影响的一种常见模式是PDF文件生成

如本文档https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox中所述 - 支持以下PDF生成器:

•SQL报告框架:要求网站以Basic或更高版本运行 (请注意,这当前在消费模式下的功能应用程序中不起作用)

•EVOPDF:有关供应商解决方案,请参阅http://www.evopdf.com/azure-html-to-pdf-converter.aspx

•Telerik报告:要求网站以Basic或更高版本运行。

•Rotativa / wkhtmltopdf:要求网站以Basic或更高版本运行。

•NReco PdfGenerator(wkhtmltopdf):要求订阅计划基本或更高

答案 1 :(得分:0)

实际上,我认为问题在于Azure的GDI不支持EMF,Telerik Reporting的桌面查看器和ReportProcessor在打印时会使用EMF。但是,在R2 2018 SP1中,该问题已解决,可以调整打印格式,以便引擎将使用Bitmap而非Azure支持的图元文件进行打印。有问题的渲染扩展名为ImagePrint,可以通过应用程序的配置文件进行设置,如下所示:

<configuration> 
  <!-- The configSectins element should be the first child element of configuration --> 
  <configSections>
  <section
    name="Telerik.Reporting"
    type="Telerik.Reporting.Configuration.ReportingConfigurationSection, Telerik.Reporting, Version=x.x.x.x, Culture=neutral, PublicKeyToken=a9d7983dfcc261be"
    allowLocation="true"
    allowDefinition="Everywhere"/>
  </configSections>
       
  <Telerik.Reporting> 
    <extensions> 
      <render> 
        <extension name="IMAGEPrint"> 
          <parameters> 
            <parameter name="OutputFormat" value="PNG"/> 
            <parameter name="DpiX" value="300"/> 
            <parameter name="DpiY" value="300"/> 
          </parameters> 
        </extension> 
      </render> 
    </extensions> 
  </Telerik.Reporting> 
</configuration> 

DpiX DpiY 参数不是强制性的,但由于默认情况下将其设置为96,因此可能会导致图像像素化,特别是在使用DPI较高,因此最好也通过app.config对其进行配置。