Aspnetcore: Asp.Net核心报告(SSRS)

创建于 2016-06-02  ·  269评论  ·  资料来源: dotnet/aspnetcore

我正在使用ASP.NET Core应用程序,找不到用于显示SSRS报告的解决方案。 随着“ Microsoft.Reporting.WebForm”的缺席不再起作用。 在ASP.NET Core中在网络上显示SSRS报告的最佳实践是什么

External

最有用的评论

将近2年。 Core 2.0已发布。 SSRS团队,醒来。

所有269条评论

由于Core仍在RC(本月底为RTM)中,我不认为在接下来的6个月内计划SSRS方案,但是我不属于团队。

我要么使用一些JavaScript库在客户端生成这些报告,要么预生成这些报告。

如果您需要更多“集成”的东西,可以查看以下社区软件包:

https://github.com/ilich/MvcReportViewer

通过查看问题https://github.com/ilich/MvcReportViewer/issues/121 ,他们对集成它很感兴趣,但到目前为止还没有成功。

我不明白为什么dotnet和ASP.net核心计划在以前的所有公告中都对此问题保持沉默。 它就像是
[报告不是开发人员的主要问题,他们可以使用html和print css类来处理报告]
当前,我们正在迁移带有许多ssrs rdlc文件的小型erp,css方法在跨浏览器报告中没有任何用处。
另一方面,上周微软发布了带有纯html5查看器的ssrs 2016,从而消除了对Activex安装的需求[这是在非IE浏览器上使用ssrs的唯一缺点]
ssrs 2016 viewer完美适合asp.net核心生态系统
但是没有宣布有关asp.net核心支持的正式声明。

全部被System.Drawing阻止了吗? 因为直到现在itextsharp都没有发布库。
如果是System.Drawing,则至少可以在[linux和OSX]之前完成Windows实现,以增加当前Windows开发人员的采用率,而不必等待System.Drawing的完整跨平台实现

我希望这篇文章能使团队重新考虑一些优先事项,以便在asp.net核心中启用ssrs

关于上一篇文章中提到的MvcReportViewer(它是webforms查看器的包装),它过去帮助很多mvc开发人员克服了mvc1到mvc5中缺少mvc报告查看器的问题[非常感谢ilich],我希望看到完整的解决方案,因为ssrs并不是头等大事,人们在前核心mvc中都保留了它。

请开发人员,
将此问题转发给您的同事以对此发表评论。
这可能会优先考虑,并激励团队去做一些事情。

@ ddddddddeee22211这是V1。

您最初不附带SSRS支持。 SSRS的支持可能来自SSRS团队,而不是.NET团队。 由于我们还没有脱离RC,因此我不认为这是V1中的关键功能。

如果您需要做报告,我是否建议您仅运行Webforms版本? 是的老了但是至少它可以工作并且得到支持。

如果您需要X-Plat报告,建议您使用Chartist 。 它使您可以直接在客户端上生成图表。 添加CSS文件用于打印目的和繁荣。 您有可以打印的报告。

从您的角度来看可能并不重要
但是其他一些开发人员则认为这对他们的项目非常重要,因为一旦开发了应用并投入使用,开发任务就会被保留,而报告任务将成为日常例行任务。 还有一些项目负责向BI(商业智能)团队创建报告,他们知道如何使用ssrs,但是对asp.net核心一无所知。

我的帖子的目的是了解ssrs在asp.net核心生态系统中的位置。 还是将其忽略(如在mvc1到mvc5中一样)。 ssrs团队在Microsoft内部,asp.net核心团队可能会与他们讨论此问题。
令我发疯的是上周我看到ssrs 2016发行说明时未提及任何有关asp.net核心的信息。 另一方面,您会在asp.net核心中看到对azure的持续支持。请相信我,如果我们对ssrs的需求没有增加,它将像以前的mvc 5一样被忽略。

您关于使用Webforms的建议是放慢采用核心主动性的一个示例。至少如果我有关于是否支持它的声明,我将能够对此做出战略决策。

感谢您的聊天技巧。 我会检查一下,希望您理解我的观点。

@ ddddddddeee22211啊...然后我无法回答。

现在,使SSRS组件在ASP.NET上运行的唯一方法是在WebForms上。

如果您需要他们的战略职位或他们会支持它,我们将需要等待MS员工回答。

也许我们可以/ cc @coolcsh吗? 他可能不会在这里回答,但在博客中阐明其立场会很好。

在SSRS团队中,我们意识到ASP.NET WebForms的局限性,我们正在积极研究和研究Report Viewer控件的新选项。
谢谢

@jtarquino

感谢您的回复!

自MVC以来,我们一直在寻求替代方案。 :stuck_out_tongue_winking_eye:

那一天让我开心。 [〜幸福的结局〜]
感谢@jtarquino@MaximRouiller的所有努力。

@jtarquino
听起来不错 :-)

关于扩展发布Report Viewer Control的“新选项”的第一版的时间,您能说什么吗?
(是否有任何路线图/计划?)

Br。
e

不幸的是我目前没有时间表

您是否通过在Package Manager控制台上安装Package并在命令窗口中键入以下命令来尝试使用库?

PM>安装包ReportViewerForMvc
虽然我已经尝试过Web表单,但它们看起来还不错。

untitled

@bethwellagat
再次引发错误“
笔记:
在ASP.NET Core项目上工作

@jtarquino ping对此。 似乎有更多的兴趣: https :

@jtarquino BTW如果您想与我的团队开始一些讨论,请给我发送电子邮件,我们可以聊天。

哦,我喜欢! 球在滚! 😀

大家好,我刚刚使用内置在SSRS中的ReportExecutionService.asmx编写了报表查看器控件的自定义端口,并且我的目标是ASP.NET MVC。 我有人建议将其移植到.NetCore和MVC,所以我已经完成了。 试试看,让我知道你们的想法: https :

艾伦

自从这里讨论了ASP Netcore MVC中的ReportViewer以来,似乎已经过去了大约三个月。 我正在使用Alan Juden从WinForms迁移到netcore的项目中提供的版本。 微软是否有迹象表明将提供一流的SSRS ReportViewer支持,或者是否将SSRS放在几年前将Visual FoxPro放在同一个壁橱中?

MS有进步吗? 目前最好的选择是使用第三方工具,例如Telerik Reports进行浏览器渲染,使用SSRS后端进行报表订阅。 也许就像ddddddddeee22211所写的那样,SSRS 2016已经具有通过HTML5呈现引擎​​的功能,但是没有文档吗?

嘿@Eilon。

自9月以来有什么消息吗? 特别是由于你们现在已经发布了1.0(恭喜!),压力一定要减轻一点。

您有什么可以分享的吗?

/ cc @jtarquino

我尚无法分享任何内容,一旦有了.NET core的新闻,您将成为第一个知道的人。
正如您提到的,我们刚刚发布了ASP.NET Webforms和Winforms控件的最新nuget。

我也想向团队添加提示...这是一个主要问题。 我感谢AlanJuden的解决方案,但是我们需要一个“正式的”解决方案...鉴于核心1现已淘汰了几个月,因此对这一现状有所了解将很有帮助。 如果您能在时间表上让我们说出解决方案,那将是一件好事。 这个问题足够大,它将阻止我们使用mvc core。 一注。 我们确实需要一个能够解决用户登录ssrs服务器的需求的解决方案。 这就是为什么我的项目必须使用当前的reportviewer的原因(使用reportviewer,我们让mvc项目为所有用户提供ssrs服务器的标准登录名)

SQL Server 2017现在是社区Preview2

.net标准2.0版本以最新公告关闭
而且仍然没有关于本机asp.net核心报告服务查看器的消息
请邀请其他开发人员对此问题提供反馈,并让团队意识到为每个开发人员梦dream以求的杰作框架付出如此努力的必要性。

@jtarquino :是否有SSRS的论坛或用户
用户如何联系SSRS团队?

谢谢,我真的很想在我的新应用程序与SSRS一起使用方面获得一些帮助。
是否有任何方法可以获取Web窗体控件使用的代码以插入aspx页面?
我想看看是否可以制作一个有角度的2视图,该视图“像”和“像” Web窗体控件。

你好

我们希望将我们的某些网站等迁移到asp.net核心,但其中一些包含SSRS报告查看器控件。 .net核心的报表查看器控件是否有任何进展?

谢谢
提姆

如果您针对的是Full .NET 4.x而不是.NET Core,请在迁移到ASP.NET Core之前考虑此#2022。
ASP.NET Core 2将不支持完整的.NET 4.x

@ikourfaln。 在这个阶段,要解决的问题是,在asp.net核心中没有要打破的reportviewer。 随着即将在第三季度对asp.net核心2以及.net标准2进行的更改,以及具有允许针对.net框架的兼容性垫片,我认为Microsoft不太可能为当前的asp.net核心编写一个reportviewer 1.1。

目前,我已经尝试进入SSRS的auth扩展,并且发现它真的很麻烦,可以尝试进行更改,您可以输入新的auth / login,但是当您尝试启用CORS时,We​​b应用程序可以调用SSRS要生成报告,浏览器无法收到OPTIONS的预检请求,该请求就此结束了。

所以现在我要制作一个Web表单Web应用程序,向其中添加OpenId Connect支持,以便可以在闪亮的新角度应用程序和报告之间进行SSO工作

那么我将看看我是否可以将它们与iframe hackery或其他方法结合在一起。

希望微软会更新ssrs,使其与新的网络技术更好地兼容。

另一思路:SSRS KPI和移动报告:是否可以在Web应用程序中使用它们?

@alanjuden有机会配置您的软件包以启用rdlc报告呈现吗? 为每个客户端安装Reporting Server并对其进行管理确实很痛苦。

@IonRobu ,我可能疯了……但我并不那么疯狂! :P

我不会这样做的真正原因是因为我仅使报表查看器成为前端查看器。 我完全依靠SSRS来呈现报告,并通过SSRS API给我返回报告数据。 因此,它需要具有报表服务器后端。 抱歉,但是这比我在该项目上要做的工作还要多。 我创建了MvcReportViewer作为一种简单的解决方案,以解决将控件的ASP.NET WebForms版本引入的烦恼。

报表服务器或RDLC,称为“客户端报告”
报表服务器需要更多的工作来设置和管理,是的。
但是它有很多好处:

报告在后端服务器上呈现,这减轻了前端Web服务器的工作负担。
报告的结果可以兑现,这可以减轻生产sql服务器的工作量。
复杂的报表可以按计划运行,并且可以在系统上用户很少的情况下工作,并且
然后可以从该预编译快照中提供请求。
也使用SSRS,SQL服务器连接字符串保留在报表服务器上,不需要在Web服务器配置文件中进行管理
SSRS服务器也成为报告作者可以发布到的中心,所有用户都可以从服务器获取报告。
SSRS可以设置将报告自动发送给用户,您可以将链接发送给某些用户到报告服务器,将pdf,word或excel文件发送给其他用户。

如果您需要服务更多的用户,则可能需要先添加更多的Web服务器,然后再需要更多的报表服务器,这样便无需将大量rdlc文件复制到所有Web服务器。

所以是的,如果您只有几个报告并且不需要任何使用rdlc的好处。
但是对于需要向许多用户提供大量报告的大型系统,SSRS服务器具有一些非常好的好处。
同样,SSRS api的功能非常强大,例如,您可以调用api返回报告pdf,而无需任何客户端Web表单或mvc查看器控件。
api还可以管理报告,将报告上传到服务器,设置权限并列出报告。
在工作中,我正在使用api允许我们的客户端应用列出用户可以运行的报告,以检查报告所需的参数,然后为用户运行报告。

因此,请好好看看好处,而不仅仅是管理开销。

@figuerres
客户报告在与您描述的上下文不同的环境中表现出色
许多客户不使用报表服务器,也没有合格的人员来管理和维护其问题
同样,当您为每个客户端运送带有自定义报告(60+)的产品时,您还将面临部署应用程序+部署报告的开销。
许多用户不是技术人员,他们可以理解服务器生成的报告并根据响应进行呈现,而无需先预览它们(例如,与将多个更正的发票下载到不同的选项卡中相比,可以通过查看器轻松地验证发票)

如您所见,与复杂方案相比,用户更容易适应简单的报表查看器
同时,开发人员也花费了无数的精力来开发客户报告,现在它们在实际使用中变得毫无用处

我希望微软团队理解我们的痛苦

不太确定我是否能理解您所说的所有内容,但是可以,客户报告很有用,我只是在概述服务器的原因,为什么值得一看。 您的里程可能会有所不同。

如今,网络标准2发布了,带有更多用于系统的api界面。
这可能是srss团队有机会谈论有关asp.net core的ssrs查看器的机会吗?

我公司严重依赖RDLC报告PDF格式的出口文件。 在.net core中无法执行此操作基本上是使用.net core并在docker等其他平台上运行的阻碍。

我希望每个编码人员都鼓励他/她的同事在这里对这个问题发表评论

对于那些仍在寻找解决方案的人:
如果安装了Java,则可以选择嵌入Eclipse BIRT或JasperReports。
在这两者中,JasperReports绝对是最好的SSRS替代品(稍微复杂一点,但功能也更强大/像素完美)。
它具有独立的可嵌入式报告服务器,能够访问任何JDBC数据源,还可以访问BigData,例如Cassandra或Apache Spark(SparkSQL)。

它提供报告和分析功能,可以将其实时或调度的关键任务信息实时或按计划交付给浏览器,移动设备或电子邮件收件箱,从而可以嵌入到Web或移动应用程序中,并充当企业的中央信息中心。各种文件格式。

您可以通过Launch4j提供BIRT / Jasper,从而对Java运行时进行独立的部署。

@jtarquino对.Net Core有什么好消息吗?

我不能相信这是在提出问题后约15个月的问题。 非常失望。

我们真的需要它工作,甚至是简单的指向SSRS,ReportName和Params的地方,都可以在DIV中打开。 我们花了很多时间直接在SQL上创建SSRS报告,我需要一种在简单的Core2.0 MVC应用程序中显示它们的方法。

有小费吗?

@cgountanis ,这对我
https://github.com/aspnet/Home/issues/1528#issuecomment -259169426

@cgountanis
您需要报告的pdf格式还是完整的交互式报告,如Web门户显示的内容?

我可以为您提供一些入门知识,帮助我了解如何从有角度的应用程序中进行操作

这就是我在做什么。 使用可能不适用于大多数客户的凭据。
调整页面大小会更大,而不会变小。


<strong i="7">@model</strong> string

@{
    ViewData["Title"] = "View Report";
}

<style>
    body {
        overflow-x: hidden;
    }
</style>

@{
    var src = "http://192.168.0.1/ReportServer/Pages/ReportViewer.aspx?/";
    src += ViewData["argument"];
}

<iframe style="overflow:hidden; overflow-x:hidden; overflow-y:hidden; border:none; width:100%; height: 1250px;" src=@src></iframe>

一件事是使用报表服务器Web服务,从中可以获得报表和文件夹以及数据源等的列表,然后使用该数据构建自己的门户/报表菜单并管理用户可以在其中查看哪些报表您的应用。
我们在报表服务器上创建了一组Windows用户,并使用它们来限制他们获取哪些报表,
将应用程序用户角色映射到报表服务器用户。

当我们运行报表时,我们会将报表服务器用户作为运行报表的用户传递给用户,这很糟糕,因为除非我们将其记录在代码中,否则我们将失去“真实用户”。
但这处理了报表服务器对Windows用户帐户的依赖。 如果他们将其更新为使用jwt令牌并从令牌中获取角色,那么对我们来说会更好。

我们使用iframe将Web窗体控件放入角度应用视图中,这也不是最好的方法,但它可以工作。
用户无法真正看到我们所做的幕后黑手。

@ ctrl-brk我在Core 2.0中遇到这个问题,也许我错过了一些东西。 https://github.com/alanjuden/MvcReportViewer/issues/43

@steelwil谢谢,但是我需要自定义NetworkCredential。

@figuerres我们显示来自防火墙的SSRS的报告,WebForm应用程序对SSRS.ReportViewer进行了所有艰苦的工作,而不仅仅是Windows用户。 同意的JWT会很好。 例子很酷,试图将WebForms / NUGET的ReportViewer功能与之匹配。

谢谢大家!

最终他们将为此权利发布官方的NUGET吗?

@cgountanis “他们”是SQL Server团队,而不是ASP.NET Core团队。 问题就在这里。 这是另一支球队。

@giddev ,这里真正的问题是,您所指的另一个团队是否实际上仍然存在于Microsoft并拥有仍在该团队中工作的活跃开发人员,以及他们是否对自己的工作感到足够自豪以产生并发布用于嵌入SSRS的一流解决方案报告到ASP.Net Core 1或2 Web应用程序。 他们有公开的路线图吗? 是ASP.Net Core计划的一部分,还是SSRS被放弃并被POWER BI替代? 我开始看到有迹象表明SSRS即将与Microsoft Visual FoxPro陷入同样的​​困境。

@wqwalter之类的东西.....
我给人的印象是,微软可以让许多团队遵循各自的地图,而没有多少人可以确保他们之间具有共同的交付和沟通方式。
就像放牧猫,它们都朝着不同的方向起飞....

如果那是错误的-那么看起来就是那样。

我发现很难相信他们会放弃SSRS,因为由于Crystal Reports不受欢迎,SSRS被开发人员广泛使用。

@cgountanis
尽管我喜欢Microsoft的某些产品,但我已经看到他们20年的历史了,他们反复停止产品并做违背我理解的事情。 一个例子是被微软收购的Virtual PC,由Microsoft出售了一段时间,然后他们将其释放,然后将其杀死。
那只是许多这样的情况之一。

我确实听说过有关Power BI的话题和八卦,可能是及时发布了新的SSRS。
我不确定这是肯定的还是八卦。 它将遵循推动基于Azure的服务的模型。

很高兴看到SSRS支持基于Web的身份验证-最好是OpenID Connect-开箱即用。 更进一步-如果SSRS是ASP.NET Core的小菜一碟,那就太好了。 报告计划和用户管理-可能提供一个示例项目,但如果提供有关SSRS API的文档,我可以开发该部分。

@摩org
同意!
OIDC非常适合我的工作。
需要完成角色,以便我们可以提供报表服务器角色到应用程序角色的映射。

现在我有一个使用OIDC和Angular 4/5前端的应用程序,它必须将Web表单报告页面加载到iFrame中,并且必须使用Windows用户帐户来控制权限,因此如果我查询报告服务器数据库,我可以实际上看不到哪些用户在运行报告。 我们可以使用它,但远非理想。

对于我们来说,这也是一个重大问题,我真的不敢相信我们仍然没有收到Microsoft的任何消息。 这严重地使我们在这一点上考虑了非微软的选择。 如果至少有时间表,我们可以做出明智的决定。

我同意,我已经走了直接使用ReportServer / ReportExecution2005.asmx的路线,只是为了直接进行导出。 当托管在IIS下时,如果出现奇怪的错误,效果很好。

真令人沮丧。

System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was ''

该错误表明授权标头丢失,http请求需要包含标头。 请问一个人有问题吗?

在托管在IIS下之前,可以正常工作。 甚至我的开发机器都在与同一个报表服务器通信,并且可以正常工作,但是一旦发布并托管了II,就会出现该错误。 想想这是在说服务器正在响应某种错误为空,但我正在向其发送所有信息。

请记住,IIS Express在您的用户凭据下运行,因此双跳可能很好。 可能发生的情况是您没有在IIS服务器上设置kerberos,即使您打开了委派,报表也无法正常工作,因为该报表是以匿名身份运行的。

简短的答案:如果没有设置kerberos,则不能使用委托,这需要在域控制器上为IIS App Pool运行的帐户进行设置。

https://blogs.msdn.microsoft.com/chiranth/2014/04/17/setting-up-kerberos-authentication-for-a-website-in-iis/

我知道这不是合适的地方,但我想跟进。 在IIS上托管Core,它不在乎将IIS设置设置为什么。 仅针对S&G,我使appPool用户成为Administrator,并且它可以正常工作。 图...除了匿名以外,没有启用IIS身份验证设置。 有人解释吗? 它是否需要访问需要特殊访问权限的Core上的WCF库? 是什么赋予了? 我感到困惑...并担心安全性。

@cgountanis您可以问一个新问题吗?

@jtarquino您是否对基于.net核心的报表查看器发布的时间表有任何更新? 我渴望至少有一个时间表。 我们在说六个月吗? 12个月? 基本上,我们面临着放弃所有当前SSRS报告并采用其他解决方案的决定,因为我们没有其他选择,也没有任何可用性的时间表。

@ExcaliburVT它在我们的待办事项列表中,但是我目前没有可以提供的时间表。

@jtarquino开源很不错,而且除了微软之外,所有这些都需要对客户负责,客户需要为产品付款,客户需要交付产品。 我们是客户。

这是Microsoft迁移程度不高的领域。 如果我们作为客户无法获得正确的答案,那么我们会回来多久?

同样的事情正在多种产品中发生,而不仅仅是这种产品。 如果我们无法获得开展业务所需的更新,为什么我应该建议我的经理许可SQL Server和SSRS的下一版本?

@jtarquino我必须同意@figuerres,因为我刚刚进行了3个月的战斗,获得了在Oracle上使用SQL的批准,并找出了我的主要卖点之一。 我抨击Oracle没有可用的.Net Core驱动程序,而且它们至少有一个已宣布的发布日期。 SSRS是您自己的产品,您完全落后了两代,甚至没有建议的解决日期。

使用新的VS2017 WCF连接器服务(核心2)确实可以将带有参数的报告导出到PDF,Word,Excel,CSV ...如果在发布此查看器NUGET包之前需要帮助,则非常容易。 是的,您必须使用SSRS随附的ReportExecution2005.asmx,但无论创建什么,都必须使用。 我们只是决定暂时转储查看器方面,并直接下载文件。

编辑:只有问题与我前面提到的AppPool权限有关。

顺便说一下,我从Web api获取报告为pdf,并且我不使用任何wcf位。
只是soap / asmx调用和http调用。
在这样做的时候,我通过了credentails,没有任何问题。
我的代码是asp.net 4.6 / web api 2
如果您想看看我在做什么,我下周可以在github上放一些代码供您查看。
我将报表服务器称为2016,但我所做的大部分工作都将与较旧的ssrs版本一起使用。

使用SSRS(RDLC设计器)的Core 2有什么新功能吗?

@figuerres,如果您在github请求中放置了任何代码,请共享链接。

@apondu
将在下周发布,直到那时才上任。 到目前为止,没有人要求输入代码。

我正在使用Intranet应用程序Angular5 / .NetCore2 MVC5(来自MS的当前RC堆栈),我们正在使用SSRS 2012,并且需要为非登录Windows帐户的用户创建基于时间的报告订阅。

@figuerres也许您有一些想法?

您可以使用SSRS和内置的报告执行服务来整天吐出PDF。

@cgountanis谢谢您这么快速的回复,您帮助我意识到我在描述我需要做的事情时不够准确。 我已经将原始评论更新为“创建基于时间的报告订阅”

嗯,我认为是通过将订阅计划行直接插入到报表数据库中来实现的(猜测订阅服务如何基于表和现有行工作)。

@ExcaliburVT到目前为止,我已经使用SOAP API和大型SP与数据库进行交互,并且希望避免直接修改数据库。 我很高兴知道有一个后备选项。

您所说的基于时间的是什么意思?

您是否需要在特定时间运行报告?
用户执行某项操作时是否需要运行报告?

@figuerres基于时间,这意味着定期执行计划,例如每个星期三的上午8点。

是的,我无法找到一种方法,而不必至少在SQL 2012之前手动插入一条记录。如果我没记错,您不必修改架构或任何东西,只需在订阅表中插入一行即可通过这种方式将报告发送到通讯组。

好的,然后报表服务器门户可以在计划的计划上运行报表,可以将其保存到文件中或在该时间发送电子邮件。
您无需在运行时让任何人登录。

您只需从门户网站创建订阅。

您也可以从soap api进行此操作,但我不确定要进行的api调用的确切集合。

在谈论我从soapAPI看到的内容之前,请允许我提供更多背景信息。

我正在编写一个使用SSRS soapAPI和诸如“ ssrsReportWebAdmin”之类的凭据的webapp。 目前在开发中,“ ssrsReportWebAdmin”具有所有安全角色,但根据文档看来,似乎需要Content Manager角色。 用户将使用webapp为其他人创建订阅,并通过soapAPI提交这些请求。

CreateSubscriptionAsync调用返回错误,表明用户没有权限。

因此,调用api时,您正在传递具有所有角色的用户“ ssrsReportWebAdmin”的cred对象,但会收到错误消息,该对象没有权限? 有趣....

从我读过的SSRS来看,是进行设置的,所以唯一可以创建标准(定期,基于时间)订阅的人就是用户自己。 可以通过Content Manager角色设置数据驱动的订阅。

请参阅ContentManagerTasks-管理所有订阅
https://technet.microsoft.com/zh-CN/library/ms159693(v = sql.105).aspx

请参阅标题开头的第一句话“ Reporting Services支持两种...”
https://docs.microsoft.com/zh-cn/sql/reporting-services/subscriptions/subscriptions-and-delivery-reporting-services#bkmk_standard_and_datadriven

@figuerres @ExcaliburVT
我能够使用具有Content Manager SSRS角色的AD帐户创建电子邮件和文件共享的标准订阅。 从我可以看到的权限问题来看,我星期五遇到的是空白/格式错误的MatchData参数的副作用。

将近2年。 Core 2.0已发布。 SSRS团队,醒来。

@ codehippie1不要那么粗鲁。 我们都是人类。 长大!

这只是开发者洞穴中的一个玩笑。 没有冒犯的意思。 开玩笑的是,ReportViewerForMVC从2014年初开始有72,799个下载(https://www.nuget.org/packages/ReportViewerForMvc)。 SSRS团队多年来一直忽略ASP.NET MVC,现在已经忽略了2年。 说到粗鲁,有72,799次。

我希望可以将其导出为正式支持的PDF库,而如今这些浏览器不再需要具有响应性要求的状态。

@cgountanis :生成一个HTML模板(正确的纸张大小-仅html,图像为base64,内联样式)。 填写占位符,不要忘记将HTML编码设置为utf8。 将文本发送到wkhtmltopdf的StandardInput-从wkhtmltopdf的StandardOutput获取输出。 然后,您拥有比SSRS好得多的东西。

@cgountanis我已经考虑过这种方法,但是要生成一个具有页面页眉/页脚和逻辑位置换行符的像素完美报告并不容易。

对于所有与我一样痛苦的人,他们在aspnet核心上没有MS RDLC本地报告查看器; 我已经尝试了来自mozilla的pdfJs和ViewerJs的替代方法-带有MS RDLC报告查看器的pdfJs演示,以字节为单位吐出报告。 对我来说,这是两全其美的选择,因为我仍然可以使用RDLC文件,使用它们在服务器端生成报告,并具有内置于文档查看器中的功能强大的firefox以显示输出。 PdfJs仍然不是报表查看器,但就我的页面导航,打印预览,搜索和许多其他有用功能而言,它也不例外。

如果您有兴趣,这里有一个要点可以帮助您如何在aspnet核心应用程序中使用它(客户端在angular 2或更高版本,rxJs和Typescript)。 对我来说,这简直就是两全其美。

如何在Angular 2应用程序中添加pdf.js和viewer.html。(使用MS Local RDLC报告查看器生成可选的aspnet core / webapi / mvc后端报告)

我相信,您可以使用react或任何其他客户端库很好地更改angular 2,但是原理保持不变。

它可以直接与SSRS一起使用吗?

@cgountanis的前一个帖子是RDLC,这意味着没有报表服务器,Web服务器将呈现报表。

微软的一个有趣的更新...

https://blogs.msdn.microsoft.com/sqlrsteamblog/2018/04/02/microsoft-acquires-report-rendering-technology-from-forerunner-software/

我们很高兴地宣布,我们已经从Forerunner Software https://forerunnersw.com/获得了技术,以加快对Reporting Services的投资。 除其他事项外,该技术还包括Reporting Services(* .rdl)报告的客户端呈现,用于查看报告的响应UI小部件以及用于将报告集成到其他应用程序的JavaScript SDK,这证明了我们的合作伙伴可以在此基础上实现的目标我们的开放平台。

这对您来说是个好消息,因为我们看到了将这项技术应用于我们收到的多个反馈点的机会:

  • 您正在寻找可以运行SSRS报告的云软件即服务(SaaS)或平台即服务(PaaS)。 正如您可能在我们的Spring '18发行说明https://aka.ms/businessappsreleasenotes中看到的那样,我们正在积极致力于将SSRS报表引入Power BI云服务中,并且我们正在将客户端渲染添加到使这成为可能。
  • 您可能想使用Power BI应用程序在手机上查看SSRS报告。 我们相信,这项技术将帮助我们提供更好,响应速度更快的UI,以提供报告参数值,在报告中导航甚至查看报告内容。
  • 您喜欢Report Viewer控件,但是它是ASP.NET Web窗体控件。 您需要一些可以集成到ASP.NET Core / MVC应用程序或非ASP.NET应用程序中的东西。 希望借助这项技术,您可以提供可集成到任何现代应用程序中的基于客户端/基于JavaScript的Report Viewer。

这些都是艰巨的任务,我们尚无可分享的时间表,但请在接下来的几个月中保持关注,因为我们一直在努力与您分享我们的进展,并尽早并经常听到您的反馈。

问候

保罗


来自:丹尼·菲格拉斯[[email protected]]
发送:2018年3月23日,星期五2:19
至:aspnet /首页
抄送:保罗·谢尔顿; 评论
主题:回复:[aspnet /首页] Asp.Net核心报告(SSRS)(#1528)

@cgountanis https://github.com/cgountanis以前的帖子是RDLC,这意味着没有报表服务器,Web服务器呈现报表。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub https://github.com/aspnet/Home/issues/1528#issuecomment-375408680上查看,或使线程https://github.com/notifications/unsubscribe-auth/AEHciZa6-静音

哦,天哪,这不是jQuery废话了。
膨胀软件。
不仅是肿的软件,而且还很慢wwwwww ...

如果需要定义膨胀软件,这将是一个很好的选择。
为了完善起见,它基本上只缺少jQuery UI,但是我很确定执行此类操作的人仍然会找到时间为datepicker添加它。

哦,等等,我刚刚看到

jquery-ui-1.10.3.forerunner.js

我的坏,没关系。
这绝对是一个完美的例子。
我们当然不只是添加jQuery-UI,我们还推出了自己的修改版本。

天哪,这看起来像胡扯。 紧随CrApple iPad和台式机上的触摸屏之后,电话报告-正是我们需要的东西-
而且我仍然愿意使用SSRS与代理服务器一起工作,或者能够进行auth-cookie共享(基于多租户虚拟名称的托管-单域多虚拟目录iframe包含而不会忽略auth-cookie另一个虚拟目录)。 或者,如果它(在SSRS 2016+中)将在IE和Chrome以及可能的Firefox上平均呈现表格边框。
或者只是为了能够通过查询字符串手动设置区域性,翻译参数标题并自己动手做那个日期选择器,因为MS无论如何都不会正确使用它...

这是膨胀软件的定义:

<link href = "~/Forerunner/Common/css/Forerunner-all.css" rel="stylesheet" />
<link href = "~/Forerunner/Lib/jQuery/css/jquery-ui-1.10.3.forerunner.css" rel="stylesheet" />
<link href = "~/Custom/Mobilizer.css" rel="stylesheet" />

<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery-1.11.0.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/jquery.hammer.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/json2.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/scroll-startstop.events.jquery.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/jquery.lazyload.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jsTree/jstree.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/misc/js/jquery.FRmaphilight.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/moment.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner-tools.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner-widgets.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.form.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.watermark.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.validate1.11.1.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery-ui-1.10.3.forerunner.js"></script>
<link href = "~/Forerunner/Common/css/Forerunner-all.css" rel="stylesheet" />
<link href = "~/Forerunner/Lib/jQuery/css/jquery-ui-1.10.3.forerunner.css" rel="stylesheet" />
<link href = "~/Custom/Mobilizer.css" rel="stylesheet" />

<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery-1.11.0.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/jquery.hammer.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/json2.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/scroll-startstop.events.jquery.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/jquery.lazyload.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jsTree/jstree.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/misc/js/jquery.FRmaphilight.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/Misc/js/moment.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner-tools.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Bundles/forerunner-widgets.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.form.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.watermark.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery.validate1.11.1.min.js"></script>
<script type = "text/javascript" src="~/Forerunner/Lib/jQuery/js/jquery-ui-1.10.3.forerunner.js"></script>

怎么样:

<link href = "~/css/CustomerX/3kb_styles.sass" rel="stylesheet" />
<script charset="utf-8" type = "text/javascript" src="~/Scripts/4kb_scripts_with_async.ts.js" async="async"></script>

甚至更好

<script async="async"  charset="utf-8" src="js/loader.js?v=1"
data-js="[ 'js/HtmlToolsAsync', 'js/mainAsync' ]"
data-js-ie-edge="['js/polyfills/es6-promise-2.0.0.min', 'js/polyfills/classList']" 
data-css="['css/{@customer}/styles']" data-css-ie-edge="['css/fixes_for_crappy_browsers_only']"></script>

如果将unix时间戳附加到每个脚本和样式表,则奖励点,因此更改/修复实际上生效。 如果它通过日期时间值作为unix-timestamp而不是区域性特定的字符串,并且在日期> 2030或9999时不会失败,则扩展奖励积分。或者使用UTF8字符。 现在,从右到左的语言支持-我们不想过分限制Microsoft的限制。 他们在那之前失败了。 如果同时使用一种以上的欧洲语言(例如英语,德语,法语和意大利语),那么他们将超出我的期望。

亲爱的Microsoft,也许我还想测试报告是否翻译了所有字段,为此,我只想以其他用户的身份使用不同的语言登录-不必每次都更改浏览器的语言设置(或告诉客户如何执行此操作-这是迄今为止您的最终成就-我可能会添加一次难忘的[非常消极]体验-特别是在切换到Windows 8之后)。
如果您需要与您相关的内容-有时有时还会有一个英语用户,该用户正在为非英语用户设置的计算机上工作。 因此,如果我作为开发人员可以从应用程序中设置显示语言,而不仅仅是由用户代理语言设置来确定显示语言,那将是很好的选择。 也许您至少可以将此时间考虑在内。

但是,如果我看上面的胡言乱语,我已经可以说您不会。

顺便说一下,要在SSRS的当前版本中树立文化,您需要执行以下操作:

使用&in_language = IETF-language-tag调用报告

\ machinename \ Reporting Services \ ReportServer \ Pages \ ReportViewer.aspx


<script type="text/C#" runat="server">

protected override void InitializeCulture()
{
    string language = System.Web.HttpContext.Current.Request.QueryString["in_language"];

    if (string.IsNullOrEmpty(language))
        language = "";

    switch (language.ToLowerInvariant())
    {
        case "de":
            language = "de-CH";
            break;
        case "fr":
            language = "fr-CH";
            break;
        case "it":
            language = "it-CH";
            break;
        case "en":
            language = "en-US";
            break;
        default:
            language = "";
            break;
    }

    // System.Web.HttpContext.Current.Response.Write(language);
    if (!String.IsNullOrEmpty(language))
    {
        System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(language);
        System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
    }

    base.InitializeCulture();
}
</script>

然后需要在http请求中覆盖该语言(SSRS中的自定义HTTP模块)
(P3P策略是针对表单登录帖子位于其他域的iframe上时起作用的)。

您能否确保不提供(DISPLAY)语言参数就不要破坏它?
您的参数rs:ParameterLanguage仅影响URL中的参数,而不影响报告的显示。 并且它不必首先存在,例如,如果您只是将datetime作为unix-timestamp(UTC)传递的。 当然,您应该始终使用sameorigin标头或allow-from标头(iframe与ReportServer位于不同的域)。 顺便说一下,在HTTP模块中设置请求语言是为了将SSRS 2016的日期选择器设置为所需的语言-否则,如果JavaScript具有en-US日期选择器,则JavaScript将失败。 很好,不是吗?

怎么样:&rs:language = IETF / IANA语言标签?


namespace libRequestLanguageChanger
{


    public class RequestLanguageChanger : System.Web.IHttpModule
    {


        void System.Web.IHttpModule.Dispose()
        {
            // throw new NotImplementedException();
        }


        void System.Web.IHttpModule.Init(System.Web.HttpApplication context)
        {
            // https://stackoverflow.com/questions/441421/httpmodule-event-execution-order
            context.BeginRequest += new System.EventHandler(context_BeginRequest);
            context.EndRequest += new System.EventHandler(context_EndRequest);
        }


        void context_BeginRequest(object sender, System.EventArgs e)
        {
            System.Web.HttpApplication application = sender as System.Web.HttpApplication;
            System.Web.HttpContext context = application.Context;

            if (context.Request != null)
            {
                // string language = context.Request.Headers["Accept-Language"];
                string language = null;
                // string url = context.Request.RawUrl;
                // string referrer = null;


                if (context.Request.UrlReferrer != null)
                {
                    // referrer = context.Request.UrlReferrer.OriginalString;

                    string queryString = context.Request.UrlReferrer.Query;
                    System.Collections.Specialized.NameValueCollection queryStrings = System.Web.HttpUtility.ParseQueryString(queryString);
                    language = queryStrings["in_language"];
                }

                if (context.Request.QueryString["in_language"] != null)
                    language = context.Request.QueryString["in_language"];

                if (!string.IsNullOrEmpty(language))
                {
                    language = language.ToLowerInvariant();

                    switch (language)
                    {
                        case "de":
                            language = "de-CH";
                            break;
                        case "fr":
                            language = "fr-CH";
                            break;
                        case "it":
                            language = "it-CH";
                            break;
                        case "en":
                            language = "en-US";
                            break;
                        default:
                            language = "";
                            break;
                    }

                } // End if (!string.IsNullOrEmpty(language)) 

                // SQL.Log(url, referrer, language);


                // Simulate Browser-Language = language 
                if (!string.IsNullOrEmpty(language))
                {
                    // context.Request.Headers["Accept-Language"] = language;

                    System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo(language);
                    System.Threading.Thread.CurrentThread.CurrentCulture = culture;
                    System.Threading.Thread.CurrentThread.CurrentUICulture = culture;

                    for (int i = 0; i < context.Request.UserLanguages.Length; ++i)
                    {
                        // context.Request.UserLanguages[i] = "en-US";
                        context.Request.UserLanguages[i] = language;
                    }

                } // End if (!string.IsNullOrEmpty(language)) 

            } // End if (context.Request != null) 


        } // End Sub context_BeginRequest 



        // https://stackoverflow.com/questions/31870789/check-whether-browser-is-chrome-or-edge
        public class BrowserInfo
        {

            public System.Web.HttpBrowserCapabilities Browser { get; set; }
            public string Name { get; set; }
            public string Version { get; set; }
            public string Platform { get; set; }
            public bool IsMobileDevice { get; set; }
            public string MobileBrand { get; set; }
            public string MobileModel { get; set; }


            public BrowserInfo(System.Web.HttpRequest request)
        {
            if (request.Browser != null)
            {
                if (request.UserAgent.Contains("Edge")
                    && request.Browser.Browser != "Edge")
                {
                    this.Name = "Edge";
                }
                else
                {
                    this.Name = request.Browser.Browser;
                    this.Version = request.Browser.MajorVersion.ToString();
                }
                this.Browser = request.Browser;
                this.Platform = request.Browser.Platform;
                this.IsMobileDevice = request.Browser.IsMobileDevice;
                if (IsMobileDevice)
                {
                    this.Name = request.Browser.Browser;
                }
            }
        }


    }


    void context_EndRequest(object sender, System.EventArgs e)
    {
        if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)
        {
            System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;

            try
            {
                // response.Headers["P3P"] = "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"":
                // response.Headers.Set("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
                // response.AddHeader("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");
                response.AppendHeader("P3P", "CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"");

                // response.AppendHeader("X-Frame-Options", "DENY");
                // response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
                // response.AppendHeader("X-Frame-Options", "AllowAll");

                if (System.Web.HttpContext.Current.Request.UrlReferrer != null)
                {
                    // "X-Frame-Options": "ALLOW-FROM " Not recognized in Chrome 
                    string host = System.Web.HttpContext.Current.Request.UrlReferrer.Scheme + System.Uri.SchemeDelimiter
                        + System.Web.HttpContext.Current.Request.UrlReferrer.Authority
                        ;

                    string selfAuth = System.Web.HttpContext.Current.Request.Url.Authority;
                    string refAuth = System.Web.HttpContext.Current.Request.UrlReferrer.Authority;

                    // SQL.Log(System.Web.HttpContext.Current.Request.RawUrl, System.Web.HttpContext.Current.Request.UrlReferrer.OriginalString, refAuth);

                    if (IsHostAllowed(refAuth))
                    {
                        BrowserInfo bi = new BrowserInfo(System.Web.HttpContext.Current.Request);

                        // bi.Name = Firefox
                        // bi.Name = InternetExplorer
                        // bi.Name = Chrome

                        // Chrome wants entire path... 
                        if (!System.StringComparer.OrdinalIgnoreCase.Equals(bi.Name, "Chrome"))
                            response.AppendHeader("X-Frame-Options", "ALLOW-FROM " + host);

                        // unsafe-eval: invalid JSON https://github.com/keen/keen-js/issues/394
                        // unsafe-inline: styles
                        // data: url(data:image/png:...)

                        // https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
                        // https://www.ietf.org/rfc/rfc7034.txt
                        // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
                        // https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

                        // https://stackoverflow.com/questions/10205192/x-frame-options-allow-from-multiple-domains
                        // https://content-security-policy.com/
                        // http://rehansaeed.com/content-security-policy-for-asp-net-mvc/

                        // This is for Chrome:
                        // response.AppendHeader("Content-Security-Policy", "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: *.msecnd.net vortex.data.microsoft.com " + selfAuth + " " + refAuth);


                        System.Collections.Generic.List < string > ls = new System.Collections.Generic.List<string>();
                        ls.Add("default-src");
                        ls.Add("'self'");
                        ls.Add("'unsafe-inline'");
                        ls.Add("'unsafe-eval'");
                        ls.Add("data:");

                        // http://az416426.vo.msecnd.net/scripts/a/ai.0.js

                        // ls.Add("*.msecnd.net");
                        // ls.Add("vortex.data.microsoft.com");

                        ls.Add(selfAuth);
                        ls.Add(refAuth);

                        string contentSecurityPolicy = string.Join(" ", ls.ToArray());
                        response.AppendHeader("Content-Security-Policy", contentSecurityPolicy);
                    }
                    else
                    {
                        response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
                    }

                }
                else
                    response.AppendHeader("X-Frame-Options", "SAMEORIGIN");
            }
            catch (System.Exception ex)
            {
                // WTF ? 
                System.Console.WriteLine(ex.Message); // Suppress warning
            }

        } // End if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Response != null)

    } // End Using context_EndRequest


        private static string[] s_allowedHosts = new string[]
    {
        "localhost:49533"
            , "localhost:52257"
            , "www.companyX.com"
            , "companyX.com"
            , "vmcompany1"
            , "vmcompany2"
            , "vmbank1"
            , "vmbank2"
    };


        public static bool IsHostAllowed(string host)
    {
        return Contains(s_allowedHosts, host);
    } // End Function IsHostAllowed 


        public static bool Contains(string[] allowed, string current)
    {
        for (int i = 0; i < allowed.Length; ++i)
        {
            if (System.StringComparer.OrdinalIgnoreCase.Equals(allowed[i], current))
                return true;
        } // Next i 

        return false;
    } // End Function Contains 


} // End Class RequestLanguageChanger 


} // End Namespcae libRequestLanguageChanger 

Microsoft请不要按原样使用该代码!
现代的客户端Web应用程序正从j查询移至es模块等。
我们不需要或不想引入一堆j查询代码。
我宁愿给客户一个pdf或当前的asp.net控件,而不是这堆j查询。

制作一个与Angular 2-6,node和其他Web客户端框架配合使用的npm软件包。
还可以继续使用SSRS渲染,它有很多好处。 只需获取一组更新的Web服务api

这事有进一步更新吗?

好吧,基本上我们已经拥有了所需的一切。
我们需要的是REST / JSON版本的
http://localhost/ReportServer/ReportExecution2005.asmx
(如果我们/任何人都可以自定义网址,则不会受到伤害)
作为一个nuget软件包-也可以在Linux / Mac上使用。
唯一需要做的就是将.NET代码移植到.NET Core / NetStandard,并将所有pinvokes删除到Windows dll。 然后,添加通过Web服务输出PAGED html的功能(当前缺少-因为它在asp.net-render-control中),并允许设置下载文件名。

我们甚至可以自己完成参数选择-使用XmlDocument读取RDL。
(选项显式关闭,选项严格关闭,VB代码推断选项可能会出现一些问题)
有点像当前的ASP.NET控件,只是没有所有的ASP.NET-WebForms东西。

因此,我认为甚至没有对JavaScript的要求-无论如何,因项目而异,因公司而异,因人而异。
有些像jQuery。 有些像角。 有些喜欢Vue。 有些像React。 有些像带有NPM的NodeJS,有些像凉亭,有些像TypeScript,有些像Babel,有些流程,有些甚至使用jQuery-UI作为日期选择器。

例如,我在很大程度上讨厌所有这些框架(尤其是jquery-ui),因为它的生命周期是果蝇,版本之间存在不兼容,膨胀,非模块化以及任何事物的学习曲线,都是一群不知道自己所学的人正在做(请注意:我不想在此暗示我永远都知道自己在做什么),以及像npm / bower这样的破损包管理器,它的缺点在于每次您每次寻找新方法时都会找到新的乐趣本来想使用它们的。

因此,我只使用VanillaJS(带有ECMA模块和异步-使用babel或打字稿进行翻译-谁在乎翻译器。

当然,现在有很多人会不同意-您有权不同意,因为有不同意的原因。 最后,我不在乎您使用什么-如果您绝对愿意的话,将coffeescript和emacs与jquery-ui和vue一起使用-只是不要强迫我走这条路。 我不需要/想要jquery / angular / vue / react / bower / npm或任何那种膨胀和不可靠的东西。

现在,这就是说,如果您想提供一个JavaScript库,任何人都可以将其放置在其站点上以自动选择参数,例如在ReportServer中(而不是RDLC),并且与当前的reportviewer-control不同,我全力以赴。 即使您这样做,也要使其独立于报告“控件”。 并使用类似节点的结构来构成ECMA模块,以便希望使用节点的人可以将其与node / npm一起使用,而不必使用它们。

作为一个旁节点,如果REST / JSON版本允许以json的形式从服务中获取过滤器数据,就像呈现的文件一样,我们甚至不需要读取RDL文件,并且我们将拥有一个非常复杂的UN JS图书馆。 无论如何,参数中当前允许的VB代码将不允许在客户端执行此操作。

或进一步考虑,如果服务允许以JSON格式获取报告中的每个数据集,那就更好了。 我想我们也需要能够读取每个参数的默认值。 然后,我们甚至可以对报告中使用的SQL数据的正确性进行单元测试!
(目前还不太可能进行单元测试报告)

格式化的另一样式表将完成技巧(请使用SASS)。 而用于其他/替代渲染器的插件系统将解决这个问题。 ¨

但从根本上讲,我们实际上只需要一个多平台的报告呈现库。
社区今天已经可以完成其他所有工作。
我想如果现有控件的来源可用,那么所有或大部分所需的工作甚至可以完全由社区来完成-甚至不会花一角钱给微软。

alanjuden MvcReportViewer是否可与SSRS 2017和core 2一起使用?我可以对SSRS 2017和core 2使用这种方法吗?

不,不是没有很多头痛。 最简单的解决方案是直接使用reportexecution2005直接导出PDF,恕我直言。 试图以响应式格式吸引任何老观众,尤其是在手机和平​​板电脑上,这是一种痛苦。

@Mahenbisht ,我必须使用更新到最新版本的软件包从源代码构建它,以便使其在核心2中工作。尚未尝试过2017年。

我正在将SQL Server 2017与SSRS 2017和core 2一起使用。
如果我不能使用alanjuden.MvcReportViewer.NetCore,那么还有其他方法吗

@Mahenbisht ,我知道我有一段时间没有很活跃了……但是,您仍然可以使用类似的方法。 您始终可以连接到我正在使用的Reporting Service API(SSRS内置)来运行自己的报告,并将其以所需的任何格式放置。

@Mahenbisht :这里有一个.NET Core nuget包:
https://www.nuget.org/packages/AspNetCore.ReportViewer/
不幸的是,没有任何来源,因此您看不到它的作用和用法。
因此,我在这里对其进行了反编译(编译)。

似乎是从.NET Core的ReportExecution2005&ReportService2010-WSDL生成的类。
因此,如果您可以通过网络访问具有SSRS的SQL服务器的运行实例,那么没有什么可以阻止您编写自己的查看器。
如果我没记错的话,您需要传递deviceinfo进行渲染,以获取分页的html输出。
这使您可以手动进行参数设置-从理论上讲,这就是我目前正在研究的内容。

@alanjuden :您的方法的问题在于,它需要安装了ReportingServices的SQL Server实例。 如果有的话,您也可以将一个iframe放到/ ReportServer,然后向Reportingservices添加一些自定义身份验证+ W3C标头和语言本地化DLL。 然后,您根本不需要工作。

问题在于
A)N个客户不一定总是安装相同版本的SSRS(带有所有累积更新/服务包-就我而言,当前范围是SSRS-2008R1到2016),
B)SSRS-Express安装只能访问本地计算机上的数据库。 真正令人讨厌的是,没有在非Windows PC(Linux,Mac)上运行的ReportViewer控件-因此您必须将.NET与Java结合使用以实现Birt或Jasper-破坏了xcopy-deployment-更不用说庞大了2-3种报告格式的开销,以及整个Java JVM和birt / jasper bloatware(包括tomcat和/或其他类似废话)的开销。
C)ReportingService使用集成的Windows身份验证。 因此,即使您使用Windows,也需要为Intranet外部添加自定义身份验证,这意味着您需要具有对ReportingServices的修改访问权限,并且您的修改可能会破坏其他软件,因此,任何明智的客户都必须安装的新实例。 SSRS / SQL-Server(需要花钱)。
也D)如果不修改ReportViewer.aspx,则ReportingService参数是不可本地化的,请参阅C)
以及E)任何版本的SSRS <2016 Renders quirks-html(虽然2016+更好,但在这方面还远远不够完美,顺便说一句)
但是,由于2008年的旧版本仍会在2018年左右出现,因此2016年以下的版本要消失可能还需要5到10年的时间。 届时,SSRS 2016无疑将过时了。 如果那时微软仍然存在,那就是。

Docker可以进行救援-幸运的是。 但这仍然很糟糕。

并将一些自定义身份验证+ W3C标头和语言本地化DLL添加到reportservices。

@ststeiger是否有任何在线示例可将SSRS查看器放入iframe中,从而从主站点和W3C标头传递自定义增强功能?

@adopilot :这是一个大概的方法:

将自定义身份验证添加到SSRS

https://github.com/Microsoft/Reporting-Services/tree/master/CustomSecuritySample

(您需要对其进行一些修改,以便每个数据库使用一个用户。
您不想开始将SSRS用户和权限与表单用户同步!
仅为此数据库的文件夹授予该用户权限。

向SSRS添加一个模块设置p3p标头,并使用您选择的语言覆盖context.Request.UserLanguages [i](否则datepicker不起作用)

修改ReportServer的登录页面,以响应获取和发布参数,并设置login_cookie,然后重定向到发布到的报表。

类别FormsAuthentication_RS2012中的Page_Load中的代码程序集FormsAuthentication_RS2012中的LogOn

在表单中发布使用unix时间戳(因此无法重播)进行了unix时间戳加密的PGP / RSA加密的数据,并在page_load的FormsAuthentication_RS2012中解密该发布数据。

(无法提供FormsAuthentication_RS2012代码,因为它包含私钥和硬编码的管理员密码)


<%@ Page Language="C#" AutoEventWireup="true" Inherits="FormsAuthentication_RS2012.LogOn, FormsAuthentication_RS2012" %>

<!DOCTYPE html PUBliC "-//W3C//DTD Xhtml 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" /> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>SSRS Login</title>

    <style type="text/css" media="all">

        html, body
        {
            width: 100%;
            height: 100%;
            margin: 0px;
            padding: 0px;
            overflow: auto;
        }


        .divLayout 
        {
            float: left;
            height: 100%;
            background-color: #d4d4d4;
        }


        .spnTitle 
        {
            color: #0060a6;
            font-size: 45px;
            margin: 0;
            font-weight: normal;
            padding-top: 10%;
        }


        .spnLogin 
        {
            font-family: '?Segoe', 'Segoe UI', Segoe, Arial, sans-serif;
            font-size: 26px;
            vertical-align: middle;
            padding-left: 10px;
        }


        .btnLogin 
        {
            border: none;
            width: 204px;
            height: 64px;
            background-color: #d4d4d4;
            vertical-align: middle;
            text-align: center;
            color: #525252;
        }


        .btnLogin:hover
        {
            color: #FFFFFF;   
        }


        .btnLogin:hover .spnLoginSymbol 
        {
            /* http://stackoverflow.com/questions/7217244/style-child-element-when-hover-on-parent */
            background-image: url('<%=FormsAuthentication_RS2012.LogonHelper.GetPageName() %>?image=whiteForward_37x36.png');
        }


        .spnLoginSymbol
        {
            display: inline-block;
            width: 37px;
            height: 36px;
            background-image: url('<%=FormsAuthentication_RS2012.LogonHelper.GetPageName() %>?image=82Forward_37x36.png');
            background-repeat: no-repeat;
            background-size: 100% auto;
            vertical-align: middle;

            color: #525252;
        }


        .spnLoginSymbol:hover
        {
            background-image: url('whiteForward_37x36.png');
        }


        .lblCaption 
        {
            font-family: '☺Segoe', "Segoe UI", Segoe, Arial, sans-serif;
            font-size: .9em;
            display: block;
        }


        input[type=text]
        {
            border: 2px solid rgb(187, 187, 187);
            <asp:Literal Id="litUserNameStyle" runat="server" />
        }


        input[type=password] 
        {
            border: 2px solid rgb(187, 187, 187);
            <asp:Literal Id="litPWStyle" runat="server" />
        }


        input[type=text]:hover, input[type=password]:hover 
        {
            border: 2px solid rgb(237, 206, 0);
        }


        .CorLink
        {
            color: #BF0A1E; 
        }


        .CorLink:hover
        {
            color: rgb(103, 12, 12);
        }

    </style>

</head>
<body>

    <div style="position: absolute; top: 0px; width: 100%; height: 1.5cm; line-height: 1.5cm; vertical-align: middle; text-transform: uppercase; font-weight: bold; background-color: #000000; color: #FFFFFF; text-align: center; font-size: 13px; font-family: '☺Segoe', 'Segoe UI', Segoe, Arial, sans-serif; ">
        <asp:Literal Id="litAuthentication" Text="Forms-Authentication" runat="server" />
    </div>


    <div class="divLayout" style="background-color: #0060A6; width: 30%; text-align: center;">
        <img src="<%=FormsAuthentication_RS2012.LogonHelper.GetPageName() %>?image=mydb3.png" style="margin-top: 40%; margin-left: -50px;" alt="logo" />

        <!-- 

        <img src="accountsicon.png" style="margin-top: 30%;" alt="logo" />
        <img src="mydb3.png" style="margin-top: 30%;" alt="logo" />
        <img src="reportsicon.png" style="margin-top: 30%; width: 20%;" alt="logo" />

        <img src="hap-logo-128.png" style="margin-top: 30%;" alt="logo" />
        -->
    </div>

    <div class="divLayout" style="background-color: #F3F3F3; width: 70%;">





        <div class="greenBorder" style="display: table; width: 100%; height: 100%; #position: relative; overflow: hidden;">

            <div style=" #position: absolute; #top: 50%;display: table-cell; vertical-align: middle;">
                <div style=" #position: relative; #top: -50%">


                    <div style="display: table; margin-right: auto; margin-left: auto;padding-left: 1cm; padding-right: 1cm;">
                        <!--
                        <b>TEST environment</b>
                        -->

                        <span class="spnTitle">
                            SQL Server Reporting Services 2012
                        </span>

                        <div style="display: block; height: 30px;"></div>

                          <form id="form1" target="_self" method="post" runat="server">

                            <div>
                                <label for="txtUserName" class="lblCaption"><asp:Literal Id="litlblUserName" runat="server" />:</label>
                                <input id="txtUserName" name="txtUserName" type="text" style="width: 300px;" />
                            </div>


                            <div>
                                <label for="txtPassword" class="lblCaption"><asp:Literal Id="litlblPassword" runat="server" />: </label>
                                <input id="txtPassword" name="txtPassword" type="password" style="width:300px;" />
                            </div>

                            <div style="display: block; height: 30px; clear: both;"></div>


                            <button type="submit" class="btnLogin" style="">
                                <!--
                                <img src="82Forward_37x36.png" alt="arrow" style="vertical-align: middle; margin-top: 0px;" />
                                -->
                                <span class="spnLoginSymbol"></span>
                                <span class="spnLogin">Login</span>
                            </button>

                        </form>

                    </div>

                </div>
            </div>
        </div>



    </div>
    <!-- End divLayout -->


    <div style="position: absolute; bottom: 0px; width: 100%; height: 1.5cm; line-height: 1.5cm; vertical-align: middle; background-color: #000000; color: #FFFFFF; text-align: center; font-family: '☺Segoe', "Segoe UI", Segoe, Arial, sans-serif; font-size: 13px;">
        Copyright &copy; 2013 

        <a href="http://www.cor-management.ch" target="_blank" class="CorLink" onclick="$('html, body').animate({ scrollTop: 0 }); return false;">
            COR Managementsysteme GmbH
        </a>

    </div>

</body>
</html>

</body>
</html>

添加到ReportViewer.aspx


<script type="text/C#" runat="server">

    protected override void InitializeCulture()
    {
        string sprache = System.Web.HttpContext.Current.Request.QueryString["in_sprache"];

        if(string.IsNullOrEmpty(sprache))
            sprache = "";

        switch(sprache.ToLowerInvariant())
        {
            case "de":
                sprache = "de-CH";
                break;
            case "fr":
                sprache = "fr-CH";
                break;
            case "it":
                sprache = "it-CH";
                break;
            case "en":
                sprache = "en-US";
                break;
            default:
                sprache = "";
                break;
        }

        // System.Web.HttpContext.Current.Response.Write(sprache);
        if(!String.IsNullOrEmpty(sprache))
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(sprache);
            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(sprache);
        }

        base.InitializeCulture();
    }

</script>

将参数转换功能添加到reportviewer.aspx:

参数已写为德语/法语/意大利语/英语

在/上分割,默认为德语(您可能要使用英语)
在报告网址中添加参数in_language(in_sprache),如果您理解了这个主意,就算完成了。


function initLanguage()
{
    var language = null;
    var StyleSheetSet = null;
    var BrowserLanguage = <%= System.Web.HttpContext.Current.Request.UserLanguages != null ? "\"" + System.Convert.ToString(System.Web.HttpContext.Current.Request.UserLanguages[0]) + "\"" : "null" %>;

    if(BrowserLanguage == null)
        BrowserLanguage = window.navigator.userLanguage || window.navigator.language;

    if(BrowserLanguage != null)
        BrowserLanguage = BrowserLanguage.substr(0,2).toLowerCase();



    var dictParameters = getUrlVars(this.location.href);

    if (dictParameters != null && dictParameters.contains("rc:Stylesheet"))
        StyleSheetSet = true;

    if (dictParameters != null && dictParameters.contains("in_sprache"))
        language = dictParameters["in_sprache"];

    if(language == null)
        language = BrowserLanguage;

    if(language == null)
        language = "de";

    language = language.toLowerCase();

    return language;
} // End function initLanguage


function TranslateParameterPrompts(iLanguageIndex)
{
    var eles = document.getElementsByTagName("table");
    var strParamTableId = "ParametersGridReportViewerControl";
    var tblParameters = null;
    var ParamLabels = null;


    for(var j = 0; j < eles.length; ++j)
    {
        // console.log(eles[j]);

        if(eles[j] != null && eles[j].id != null)
        {
            if(eles[j].id.slice(0, strParamTableId.length) == strParamTableId) // if startswith str
            {
                // console.log(eles[j].id);
                tblParameters = eles[j];
                break;
            }
            // else console.log(eles[j].id);
        } // End if(eles[j] != null && eles[j].id != null)

    } // Next j


    if(tblParameters != null)
        ParamLabels = tblParameters.getElementsByTagName("span");

    // var ParamLabels = document.querySelectorAll("table[id^='ParametersGridReportViewerControl'] span");
    if(ParamLabels != null)
    {
        for(var i = 0; i < ParamLabels.length; ++i)
        {
            var strText = ParamLabels[i].innerHTML;

            if (strText != null && strText.indexOf('/') != -1 && strText.indexOf('<input') == -1 ) 
            {
                strText = strText.split('/');
                if (iLanguageIndex < strText.length)
                    strText = strText[iLanguageIndex];
                else 
                { 
                    if(strText.length > 0)
                        strText = strText[0];
                }

                ParamLabels[i].innerHTML = strText;
            } // End if (strText != null && strText.indexOf('/') != -1) 

        } // Next i

    } // End if(ParamLabels != null)

}


function fixReportingServices(container)
{
    var language = initLanguage();

    switch (language)
    {
        case "fr":
            iLanguageIndex = 1;
            break;
        case "it":
            iLanguageIndex = 2;
            break;
        case "en":
            iLanguageIndex = 3;
            break;
        default: // "DE" 
            iLanguageIndex = 0;
    } // End Switch

    TranslateParameterPrompts(iLanguageIndex);
}


// needed when AsyncEnabled=true. 
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function () { fixReportingServices('rpt-container'); });

  </script>

现在,要在某些网页上使用此功能,请创建一个名为ifrmSSRS_Login的iframe(或根据您的喜好进行调整),然后在链接单击上执行以下操作:

var data = 
{
    "issued" : datetime 
   ,"databaseName" : "foo" // name of SSRS-user 
   ,parameters : [{ "name":"forms_userid", value: 123},{ "name": "parameter1", "value": "uid1,uid2,uid3" }]
}


var valueToPost = rsa(data, public_key)

post this value with JavaScript to the cross-domain SSRS-url 



    _postSSRS: function(o){
        this._Trace('_postSSRS');

        try{
            if(!!o.SSRS_Link){
                var tF = document.body.appendChild(document.createElement('form'));
                tF.setAttribute('id', 'frm_' + Date.now());
                tF.setAttribute('method', 'post');
                tF.setAttribute('action', o.SSRS_Link + 'logon.aspx');
                tF.setAttribute('style', 'display: none;');
                tF.setAttribute('target', 'ifrmSSRS_Login');

                var HttpPostVariables = {
                     'data': o.SSRS_Data 
                    ,'SSO': 'FMS'
                };

                for(var k in HttpPostVariables){
                    var tH = tF.appendChild(document.createElement('input'));
                    tH.setAttribute('name', k);
                    tH.setAttribute('value', HttpPostVariables[k])
                };

                tF.submit()
            }
        }
        catch(err){this._Log(err, '_postSSRS')}
    },

这样,您就可以将身份验证与SSRS桥接起来,并且每个客户的用户(数据库名称)仅查看其报告(按数据库名称的ssrs权限)。

请注意,必须以小写形式传递uid,因为否则SSRS会像它一样糟糕的软件一样拒绝正常工作/爆炸。

注意:
对于多个版本的SSRS,该代码会在较长的时间段内积累,并且如果http模块覆盖了用户代理语言,那么不再需要覆盖页面初始化文化(我只有在意识到该覆盖页面之后才知道-initialize-culture对于SSRS日期选择器来说还不够好。
同样,使用斜杠作为翻译的分隔符也是不幸的。 尝试使用不需要的字符,例如£或¦。

P3P标头是必需的,因此非Windows 10计算机上的IE 11不会拒绝auth-cookie(由于ssrs在跨域iframe中运行,因此它被IE当作第三方cookie处理)。

另外,请使用SSRS 2016+,因为否则,您需要使用古怪的模式功能,例如边框宽度,高度,边距,隐藏打印功能以及所有其他“令人兴奋的IE8特定功能”等。

就像程序集名称所说的那样,这是为我们的生产服务器(SSRS 2012)完成的,而这一切都是从丑陋的SSRS 2005黑客程序演变而来的。

将链接保存在导航表的字段中,例如,将其保存为T_Navigation中的NA_Link字段
'{@report} Budget_SNB&in_user = {@ user}&in_sprache = {@ language}&rc:Stylesheet = COR_RS2012_v7'
使用baseLink,用户和语言的占位符,并设置样式表(如果背景为黑色,则需要告诉ssrs使用对其样式表的修改)

SELECT 
    REPLACE(
    REPLACE( 
    REPLACE(NA_Link, '{@report}', @reportServerBaseUrl) 
    , '{@user}', @user_id)
    , '{@language}', @user_language)
FROM T_Navigation 

并请注意,如果.NET-Framework需要重定向内部带有冒号的链接,则会出现问题。
您可以从mono项目复制用于url重定向的工作代码。

另外,请注意,您不能仅将用户ID传递为字符串/数字-它需要进行加密(私有/公共),因此没有人可以猜测用户ID。 但是首先,userid的md5-hash可能会成功。

@ststeiger @全部
AspNetCore.ReportViewer已被替换为AspNetCore.Reporting
其中包括LocalReportServerReport

@ amh1979 :不错的工作-我来看看。
我是从需要WindowsBase和pinvoke advapi32.dll / kernel32.dll / ReportingServicesService.exe的依赖项AspNetCore.ReportingServices.dll中获得的,它仅在安装了Framwork 4的.NET的Windows上有效吗?

PS:正确的英文是“ AspNetCore.ReportViewer已被>“替换为<AspNetCore.Reporting”,而不是“被替换”,但是我明白了您的意思;)
或者,您也可以说“已被种子”取代,这可能是您要查找的单词/短语;)

@ amh1979 :做得很好,不得不做一些工作,因为我没有安装框架4.7.1。
我明白了,MainStream是result / html,SecondaryStream是CSS。
但是启动并运行它。
HTML页面也很好。
您知道吗:是否有任何方法可以循环遍历所有结果或获得一个巨大的HTML文件而无需为每个页面调用render函数?

@ALL :虽然它可以在完整的.net下运行,但我无法在Windows下的.NET Core下运行。
System.Drawing.Color ToKnownColor,IsSystemColor和不存在的KnownColor问题。
修复了该问题,但现在它抱怨无法加载具有签名的程序集System.Drawing.Graphics ...

甚至没有办法在Windows的.NET Core项目中运行完整的.NET程序集吗?

@ststeiger我将在下一版本中更新并修复这些问题。

@ amh1979

在使用该工具时,如果搜索System.Array.Empty<T>并将其替换ArrayExtension.Empty<T> ,那么将它与.NET 4.0配合使用的可能性就达到了90%。

    internal static class ArrayExtension
    {

        public static T[] Empty<T>()
        {
            return new T[0];
        }

    }

@ amh1979

它使用以下内容

System.Drawing.Color c; 
c.IsKnownColor
c.IsSystemColor 
c.ToKnownColor()
System.Drawing.KnownColor enum

.NET Core的System.Drawing.Common没有实现。
这是System.Drawing.KnownColor.cs的替换
(由于模棱两可,它并不完美,但是在无法访问System.Drawing.Color的内部值的情况下。这是我能做的最好的事情-可能使用#ifs使完整的.net框架在full时调用实际属性。网络框架...)


namespace AspNetCore.Reporting.Helpers
{

    // System.Drawing.KnownColor.cs replacement 
    internal class ReportColor
    {


        private static System.Collections.Generic.Dictionary<System.Drawing.Color
                    , AspNetCore.Reporting.Helpers.AllKnownColors> SetupKnownColorDictionary()
        {
            System.Collections.Generic.Dictionary<System.Drawing.Color
                , AspNetCore.Reporting.Helpers.AllKnownColors>
                dict = new System.Collections.Generic.Dictionary
                <System.Drawing.Color, AspNetCore.Reporting.Helpers.AllKnownColors>();

            dict.Add(System.Drawing.Color.FromArgb(255, 180, 180, 180), AllKnownColors.ActiveBorder);
            dict.Add(System.Drawing.Color.FromArgb(255, 153, 180, 209), AllKnownColors.ActiveCaption);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0), AllKnownColors.ActiveCaptionText);
            dict.Add(System.Drawing.Color.FromArgb(255, 171, 171, 171), AllKnownColors.AppWorkspace);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 240, 240), AllKnownColors.Control);
            dict.Add(System.Drawing.Color.FromArgb(255, 160, 160, 160), AllKnownColors.ControlDark);
            dict.Add(System.Drawing.Color.FromArgb(255, 105, 105, 105), AllKnownColors.ControlDarkDark);
            dict.Add(System.Drawing.Color.FromArgb(255, 227, 227, 227), AllKnownColors.ControlLight);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 255), AllKnownColors.ControlLightLight);
            dict.Add(System.Drawing.Color.FromArgb(255, 109, 109, 109), AllKnownColors.GrayText);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 120, 215), AllKnownColors.Highlight);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 102, 204), AllKnownColors.HotTrack);
            dict.Add(System.Drawing.Color.FromArgb(255, 244, 247, 252), AllKnownColors.InactiveBorder);
            dict.Add(System.Drawing.Color.FromArgb(255, 191, 205, 219), AllKnownColors.InactiveCaption);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 225), AllKnownColors.Info);
            dict.Add(System.Drawing.Color.FromArgb(255, 200, 200, 200), AllKnownColors.ScrollBar);
            dict.Add(System.Drawing.Color.FromArgb(255, 100, 100, 100), AllKnownColors.WindowFrame);
            dict.Add(System.Drawing.Color.FromArgb(0, 255, 255, 255), AllKnownColors.Transparent);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 248, 255), AllKnownColors.AliceBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 250, 235, 215), AllKnownColors.AntiqueWhite);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 255, 255), AllKnownColors.Aqua);
            dict.Add(System.Drawing.Color.FromArgb(255, 127, 255, 212), AllKnownColors.Aquamarine);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 255, 255), AllKnownColors.Azure);
            dict.Add(System.Drawing.Color.FromArgb(255, 245, 245, 220), AllKnownColors.Beige);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 228, 196), AllKnownColors.Bisque);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 235, 205), AllKnownColors.BlanchedAlmond);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 255), AllKnownColors.Blue);
            dict.Add(System.Drawing.Color.FromArgb(255, 138, 43, 226), AllKnownColors.BlueViolet);
            dict.Add(System.Drawing.Color.FromArgb(255, 165, 42, 42), AllKnownColors.Brown);
            dict.Add(System.Drawing.Color.FromArgb(255, 222, 184, 135), AllKnownColors.BurlyWood);
            dict.Add(System.Drawing.Color.FromArgb(255, 95, 158, 160), AllKnownColors.CadetBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 127, 255, 0), AllKnownColors.Chartreuse);
            dict.Add(System.Drawing.Color.FromArgb(255, 210, 105, 30), AllKnownColors.Chocolate);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 127, 80), AllKnownColors.Coral);
            dict.Add(System.Drawing.Color.FromArgb(255, 100, 149, 237), AllKnownColors.CornflowerBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 248, 220), AllKnownColors.Cornsilk);
            dict.Add(System.Drawing.Color.FromArgb(255, 220, 20, 60), AllKnownColors.Crimson);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 139), AllKnownColors.DarkBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 139, 139), AllKnownColors.DarkCyan);
            dict.Add(System.Drawing.Color.FromArgb(255, 184, 134, 11), AllKnownColors.DarkGoldenrod);
            dict.Add(System.Drawing.Color.FromArgb(255, 169, 169, 169), AllKnownColors.DarkGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 100, 0), AllKnownColors.DarkGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 189, 183, 107), AllKnownColors.DarkKhaki);
            dict.Add(System.Drawing.Color.FromArgb(255, 139, 0, 139), AllKnownColors.DarkMagenta);
            dict.Add(System.Drawing.Color.FromArgb(255, 85, 107, 47), AllKnownColors.DarkOliveGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 140, 0), AllKnownColors.DarkOrange);
            dict.Add(System.Drawing.Color.FromArgb(255, 153, 50, 204), AllKnownColors.DarkOrchid);
            dict.Add(System.Drawing.Color.FromArgb(255, 139, 0, 0), AllKnownColors.DarkRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 233, 150, 122), AllKnownColors.DarkSalmon);
            dict.Add(System.Drawing.Color.FromArgb(255, 143, 188, 139), AllKnownColors.DarkSeaGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 72, 61, 139), AllKnownColors.DarkSlateBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 47, 79, 79), AllKnownColors.DarkSlateGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 206, 209), AllKnownColors.DarkTurquoise);
            dict.Add(System.Drawing.Color.FromArgb(255, 148, 0, 211), AllKnownColors.DarkViolet);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 20, 147), AllKnownColors.DeepPink);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 191, 255), AllKnownColors.DeepSkyBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 30, 144, 255), AllKnownColors.DodgerBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 178, 34, 34), AllKnownColors.Firebrick);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 250, 240), AllKnownColors.FloralWhite);
            dict.Add(System.Drawing.Color.FromArgb(255, 34, 139, 34), AllKnownColors.ForestGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 0, 255), AllKnownColors.Fuchsia);
            dict.Add(System.Drawing.Color.FromArgb(255, 220, 220, 220), AllKnownColors.Gainsboro);
            dict.Add(System.Drawing.Color.FromArgb(255, 248, 248, 255), AllKnownColors.GhostWhite);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 215, 0), AllKnownColors.Gold);
            dict.Add(System.Drawing.Color.FromArgb(255, 218, 165, 32), AllKnownColors.Goldenrod);
            dict.Add(System.Drawing.Color.FromArgb(255, 128, 128, 128), AllKnownColors.Gray);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 128, 0), AllKnownColors.Green);
            dict.Add(System.Drawing.Color.FromArgb(255, 173, 255, 47), AllKnownColors.GreenYellow);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 255, 240), AllKnownColors.Honeydew);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 105, 180), AllKnownColors.HotPink);
            dict.Add(System.Drawing.Color.FromArgb(255, 205, 92, 92), AllKnownColors.IndianRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 75, 0, 130), AllKnownColors.Indigo);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 240), AllKnownColors.Ivory);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 230, 140), AllKnownColors.Khaki);
            dict.Add(System.Drawing.Color.FromArgb(255, 230, 230, 250), AllKnownColors.Lavender);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 240, 245), AllKnownColors.LavenderBlush);
            dict.Add(System.Drawing.Color.FromArgb(255, 124, 252, 0), AllKnownColors.LawnGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 250, 205), AllKnownColors.LemonChiffon);
            dict.Add(System.Drawing.Color.FromArgb(255, 173, 216, 230), AllKnownColors.LightBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 240, 128, 128), AllKnownColors.LightCoral);
            dict.Add(System.Drawing.Color.FromArgb(255, 224, 255, 255), AllKnownColors.LightCyan);
            dict.Add(System.Drawing.Color.FromArgb(255, 250, 250, 210), AllKnownColors.LightGoldenrodYellow);
            dict.Add(System.Drawing.Color.FromArgb(255, 211, 211, 211), AllKnownColors.LightGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 144, 238, 144), AllKnownColors.LightGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 182, 193), AllKnownColors.LightPink);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 160, 122), AllKnownColors.LightSalmon);
            dict.Add(System.Drawing.Color.FromArgb(255, 32, 178, 170), AllKnownColors.LightSeaGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 135, 206, 250), AllKnownColors.LightSkyBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 119, 136, 153), AllKnownColors.LightSlateGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 176, 196, 222), AllKnownColors.LightSteelBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 224), AllKnownColors.LightYellow);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 255, 0), AllKnownColors.Lime);
            dict.Add(System.Drawing.Color.FromArgb(255, 50, 205, 50), AllKnownColors.LimeGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 250, 240, 230), AllKnownColors.Linen);
            dict.Add(System.Drawing.Color.FromArgb(255, 128, 0, 0), AllKnownColors.Maroon);
            dict.Add(System.Drawing.Color.FromArgb(255, 102, 205, 170), AllKnownColors.MediumAquamarine);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 205), AllKnownColors.MediumBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 186, 85, 211), AllKnownColors.MediumOrchid);
            dict.Add(System.Drawing.Color.FromArgb(255, 147, 112, 219), AllKnownColors.MediumPurple);
            dict.Add(System.Drawing.Color.FromArgb(255, 60, 179, 113), AllKnownColors.MediumSeaGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 123, 104, 238), AllKnownColors.MediumSlateBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 250, 154), AllKnownColors.MediumSpringGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 72, 209, 204), AllKnownColors.MediumTurquoise);
            dict.Add(System.Drawing.Color.FromArgb(255, 199, 21, 133), AllKnownColors.MediumVioletRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 25, 25, 112), AllKnownColors.MidnightBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 245, 255, 250), AllKnownColors.MintCream);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 228, 225), AllKnownColors.MistyRose);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 228, 181), AllKnownColors.Moccasin);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 222, 173), AllKnownColors.NavajoWhite);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 0, 128), AllKnownColors.Navy);
            dict.Add(System.Drawing.Color.FromArgb(255, 253, 245, 230), AllKnownColors.OldLace);
            dict.Add(System.Drawing.Color.FromArgb(255, 128, 128, 0), AllKnownColors.Olive);
            dict.Add(System.Drawing.Color.FromArgb(255, 107, 142, 35), AllKnownColors.OliveDrab);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 165, 0), AllKnownColors.Orange);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 69, 0), AllKnownColors.OrangeRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 218, 112, 214), AllKnownColors.Orchid);
            dict.Add(System.Drawing.Color.FromArgb(255, 238, 232, 170), AllKnownColors.PaleGoldenrod);
            dict.Add(System.Drawing.Color.FromArgb(255, 152, 251, 152), AllKnownColors.PaleGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 175, 238, 238), AllKnownColors.PaleTurquoise);
            dict.Add(System.Drawing.Color.FromArgb(255, 219, 112, 147), AllKnownColors.PaleVioletRed);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 239, 213), AllKnownColors.PapayaWhip);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 218, 185), AllKnownColors.PeachPuff);
            dict.Add(System.Drawing.Color.FromArgb(255, 205, 133, 63), AllKnownColors.Peru);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 192, 203), AllKnownColors.Pink);
            dict.Add(System.Drawing.Color.FromArgb(255, 221, 160, 221), AllKnownColors.Plum);
            dict.Add(System.Drawing.Color.FromArgb(255, 176, 224, 230), AllKnownColors.PowderBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 128, 0, 128), AllKnownColors.Purple);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 0, 0), AllKnownColors.Red);
            dict.Add(System.Drawing.Color.FromArgb(255, 188, 143, 143), AllKnownColors.RosyBrown);
            dict.Add(System.Drawing.Color.FromArgb(255, 65, 105, 225), AllKnownColors.RoyalBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 139, 69, 19), AllKnownColors.SaddleBrown);
            dict.Add(System.Drawing.Color.FromArgb(255, 250, 128, 114), AllKnownColors.Salmon);
            dict.Add(System.Drawing.Color.FromArgb(255, 244, 164, 96), AllKnownColors.SandyBrown);
            dict.Add(System.Drawing.Color.FromArgb(255, 46, 139, 87), AllKnownColors.SeaGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 245, 238), AllKnownColors.SeaShell);
            dict.Add(System.Drawing.Color.FromArgb(255, 160, 82, 45), AllKnownColors.Sienna);
            dict.Add(System.Drawing.Color.FromArgb(255, 192, 192, 192), AllKnownColors.Silver);
            dict.Add(System.Drawing.Color.FromArgb(255, 135, 206, 235), AllKnownColors.SkyBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 106, 90, 205), AllKnownColors.SlateBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 112, 128, 144), AllKnownColors.SlateGray);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 250, 250), AllKnownColors.Snow);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 255, 127), AllKnownColors.SpringGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 70, 130, 180), AllKnownColors.SteelBlue);
            dict.Add(System.Drawing.Color.FromArgb(255, 210, 180, 140), AllKnownColors.Tan);
            dict.Add(System.Drawing.Color.FromArgb(255, 0, 128, 128), AllKnownColors.Teal);
            dict.Add(System.Drawing.Color.FromArgb(255, 216, 191, 216), AllKnownColors.Thistle);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 99, 71), AllKnownColors.Tomato);
            dict.Add(System.Drawing.Color.FromArgb(255, 64, 224, 208), AllKnownColors.Turquoise);
            dict.Add(System.Drawing.Color.FromArgb(255, 238, 130, 238), AllKnownColors.Violet);
            dict.Add(System.Drawing.Color.FromArgb(255, 245, 222, 179), AllKnownColors.Wheat);
            dict.Add(System.Drawing.Color.FromArgb(255, 245, 245, 245), AllKnownColors.WhiteSmoke);
            dict.Add(System.Drawing.Color.FromArgb(255, 255, 255, 0), AllKnownColors.Yellow);
            dict.Add(System.Drawing.Color.FromArgb(255, 154, 205, 50), AllKnownColors.YellowGreen);
            dict.Add(System.Drawing.Color.FromArgb(255, 185, 209, 234), AllKnownColors.GradientActiveCaption);
            dict.Add(System.Drawing.Color.FromArgb(255, 215, 228, 242), AllKnownColors.GradientInactiveCaption);

            return dict;
        } // End Function SetupKnownColorDictionary 


        private static System.Collections.Generic.HashSet<System.Drawing.Color> SetupSystemColorHashMap()
        {
            System.Collections.Generic.HashSet<System.Drawing.Color> hash =
                new System.Collections.Generic.HashSet<System.Drawing.Color>(
                    new System.Drawing.Color[] {
                        System.Drawing.Color.FromArgb(255, 180, 180, 180),
                        System.Drawing.Color.FromArgb(255, 153, 180, 209),
                        System.Drawing.Color.FromArgb(255, 0, 0, 0),
                        System.Drawing.Color.FromArgb(255, 171, 171, 171),
                        System.Drawing.Color.FromArgb(255, 240, 240, 240),
                        System.Drawing.Color.FromArgb(255, 160, 160, 160),
                        System.Drawing.Color.FromArgb(255, 105, 105, 105),
                        System.Drawing.Color.FromArgb(255, 227, 227, 227),
                        System.Drawing.Color.FromArgb(255, 255, 255, 255),
                        System.Drawing.Color.FromArgb(255, 109, 109, 109),
                        System.Drawing.Color.FromArgb(255, 0, 120, 215),
                        System.Drawing.Color.FromArgb(255, 0, 102, 204),
                        System.Drawing.Color.FromArgb(255, 244, 247, 252),
                        System.Drawing.Color.FromArgb(255, 191, 205, 219),
                        System.Drawing.Color.FromArgb(255, 255, 255, 225),
                        System.Drawing.Color.FromArgb(255, 200, 200, 200),
                        System.Drawing.Color.FromArgb(255, 100, 100, 100),
                        System.Drawing.Color.FromArgb(255, 185, 209, 234),
                        System.Drawing.Color.FromArgb(255, 215, 228, 242)
                    }
            );

            return hash;
        } // End Function SetupSystemColorHashMap 


        private static System.Collections.Generic.HashSet<string> SetupKnownColorHashMap()
        {
            System.Collections.Generic.HashSet<string> map =
                new System.Collections.Generic.HashSet<string>(new string[] {
 "ActiveBorder"
,"ActiveCaption"
,"ActiveCaptionText"
,"AppWorkspace"
,"Control"
,"ControlDark"
,"ControlDarkDark"
,"ControlLight"
,"ControlLightLight"
,"ControlText"
,"Desktop"
,"GrayText"
,"Highlight"
,"HighlightText"
,"HotTrack"
,"InactiveBorder"
,"InactiveCaption"
,"InactiveCaptionText"
,"Info"
,"InfoText"
,"Menu"
,"MenuText"
,"ScrollBar"
,"Window"
,"WindowFrame"
,"WindowText"
,"Transparent"
,"AliceBlue"
,"AntiqueWhite"
,"Aqua"
,"Aquamarine"
,"Azure"
,"Beige"
,"Bisque"
,"Black"
,"BlanchedAlmond"
,"Blue"
,"BlueViolet"
,"Brown"
,"BurlyWood"
,"CadetBlue"
,"Chartreuse"
,"Chocolate"
,"Coral"
,"CornflowerBlue"
,"Cornsilk"
,"Crimson"
,"Cyan"
,"DarkBlue"
,"DarkCyan"
,"DarkGoldenrod"
,"DarkGray"
,"DarkGreen"
,"DarkKhaki"
,"DarkMagenta"
,"DarkOliveGreen"
,"DarkOrange"
,"DarkOrchid"
,"DarkRed"
,"DarkSalmon"
,"DarkSeaGreen"
,"DarkSlateBlue"
,"DarkSlateGray"
,"DarkTurquoise"
,"DarkViolet"
,"DeepPink"
,"DeepSkyBlue"
,"DimGray"
,"DodgerBlue"
,"Firebrick"
,"FloralWhite"
,"ForestGreen"
,"Fuchsia"
,"Gainsboro"
,"GhostWhite"
,"Gold"
,"Goldenrod"
,"Gray"
,"Green"
,"GreenYellow"
,"Honeydew"
,"HotPink"
,"IndianRed"
,"Indigo"
,"Ivory"
,"Khaki"
,"Lavender"
,"LavenderBlush"
,"LawnGreen"
,"LemonChiffon"
,"LightBlue"
,"LightCoral"
,"LightCyan"
,"LightGoldenrodYellow"
,"LightGray"
,"LightGrey"
,"LightGreen"
,"LightPink"
,"LightSalmon"
,"LightSeaGreen"
,"LightSkyBlue"
,"LightSlateGray"
,"LightSteelBlue"
,"LightYellow"
,"Lime"
,"LimeGreen"
,"Linen"
,"Magenta"
,"Maroon"
,"MediumAquamarine"
,"MediumBlue"
,"MediumOrchid"
,"MediumPurple"
,"MediumSeaGreen"
,"MediumSlateBlue"
,"MediumSpringGreen"
,"MediumTurquoise"
,"MediumVioletRed"
,"MidnightBlue"
,"MintCream"
,"MistyRose"
,"Moccasin"
,"NavajoWhite"
,"Navy"
,"OldLace"
,"Olive"
,"OliveDrab"
,"Orange"
,"OrangeRed"
,"Orchid"
,"PaleGoldenrod"
,"PaleGreen"
,"PaleTurquoise"
,"PaleVioletRed"
,"PapayaWhip"
,"PeachPuff"
,"Peru"
,"Pink"
,"Plum"
,"PowderBlue"
,"Purple"
,"Red"
,"RosyBrown"
,"RoyalBlue"
,"SaddleBrown"
,"Salmon"
,"SandyBrown"
,"SeaGreen"
,"SeaShell"
,"Sienna"
,"Silver"
,"SkyBlue"
,"SlateBlue"
,"SlateGray"
,"Snow"
,"SpringGreen"
,"SteelBlue"
,"Tan"
,"Teal"
,"Thistle"
,"Tomato"
,"Turquoise"
,"Violet"
,"Wheat"
,"White"
,"WhiteSmoke"
,"Yellow"
,"YellowGreen"
,"ButtonFace"
,"ButtonHighlight"
,"ButtonShadow"
,"GradientActiveCaption"
,"GradientInactiveCaption"
,"MenuBar"
,"MenuHighlight"

}, System.StringComparer.OrdinalIgnoreCase);

            return map;
        } // End Function SetupKnownColorHashMap 


        private static System.Collections.Generic.HashSet<string> m_knownColors = SetupKnownColorHashMap();
        private static System.Collections.Generic.HashSet<System.Drawing.Color> m_systemColors = SetupSystemColorHashMap();

        private static System.Collections.Generic.Dictionary<System.Drawing.Color
                , AspNetCore.Reporting.Helpers.AllKnownColors> m_knownColorDictionary = SetupKnownColorDictionary();


        // System.Drawing.Color c; c.IsKnownColor
        public static bool IsKnownColor(string color)
        {
            return m_knownColors.Contains(color);
        } // End Function IsKnownColor


        // System.Drawing.Color c; c.ToKnownColor()
        // AspNetCore.Reporting.Helpers.ReportColor.ToKnownColor(c);
        public static AspNetCore.Reporting.Helpers.AllKnownColors ToKnownColor(System.Drawing.Color c)
        {
            //System.Drawing.KnownColor knownColor = c.ToKnownColor();
            if (m_knownColorDictionary.ContainsKey(c))
                return m_knownColorDictionary[c];

            return AspNetCore.Reporting.Helpers.AllKnownColors.Unknown;
        } // End Function ToKnownColor 


        // System.Drawing.Color c; c.IsSystemColor 

        /// <include file='doc\Color.uex' path='docs/doc[@for="Color.IsSystemColor"]/*' />
        /// <devdoc>
        ///     Determines if this color is a system color.
        /// </devdoc>
        public static bool IsSystemColor(System.Drawing.Color color)
        {
            if (m_systemColors.Contains(color))
                return true;

            // return color.IsKnownColor;
            // return IsKnownColor && ((((KnownColor)knownColor) <= KnownColor.WindowText) || (((KnownColor)knownColor) > KnownColor.YellowGreen));
            return false;
        } // End Function IsSystemColor 


    } // End Class ReportColor 



    // https://raw.githubusercontent.com/mono/sysdrawing-coregraphics/master/System.Drawing/KnownColor.cs
    public enum AllKnownColors
    {
        Unknown = 0,

        ActiveBorder = 1,
        ActiveCaption = 2,
        ActiveCaptionText = 3,
        AppWorkspace = 4,
        Control = 5,
        ControlDark = 6,
        ControlDarkDark = 7,
        ControlLight = 8,
        ControlLightLight = 9,
        ControlText = 10,
        Desktop = 11,
        GrayText = 12,
        Highlight = 13,
        HighlightText = 14,
        HotTrack = 15,
        InactiveBorder = 16,
        InactiveCaption = 17,
        InactiveCaptionText = 18,
        Info = 19,
        InfoText = 20,
        Menu = 21,
        MenuText = 22,
        ScrollBar = 23,
        Window = 24,
        WindowFrame = 25,
        WindowText = 26,
        Transparent = 27,
        AliceBlue = 28,
        AntiqueWhite = 29,
        Aqua = 30,
        Aquamarine = 31,
        Azure = 32,
        Beige = 33,
        Bisque = 34,
        Black = 35,
        BlanchedAlmond = 36,
        Blue = 37,
        BlueViolet = 38,
        Brown = 39,
        BurlyWood = 40,
        CadetBlue = 41,
        Chartreuse = 42,
        Chocolate = 43,
        Coral = 44,
        CornflowerBlue = 45,
        Cornsilk = 46,
        Crimson = 47,
        Cyan = 48,
        DarkBlue = 49,
        DarkCyan = 50,
        DarkGoldenrod = 51,
        DarkGray = 52,
        DarkGreen = 53,
        DarkKhaki = 54,
        DarkMagenta = 55,
        DarkOliveGreen = 56,
        DarkOrange = 57,
        DarkOrchid = 58,
        DarkRed = 59,
        DarkSalmon = 60,
        DarkSeaGreen = 61,
        DarkSlateBlue = 62,
        DarkSlateGray = 63,
        DarkTurquoise = 64,
        DarkViolet = 65,
        DeepPink = 66,
        DeepSkyBlue = 67,
        DimGray = 68,
        DodgerBlue = 69,
        Firebrick = 70,
        FloralWhite = 71,
        ForestGreen = 72,
        Fuchsia = 73,
        Gainsboro = 74,
        GhostWhite = 75,
        Gold = 76,
        Goldenrod = 77,
        Gray = 78,
        Green = 79,
        GreenYellow = 80,
        Honeydew = 81,
        HotPink = 82,
        IndianRed = 83,
        Indigo = 84,
        Ivory = 85,
        Khaki = 86,
        Lavender = 87,
        LavenderBlush = 88,
        LawnGreen = 89,
        LemonChiffon = 90,
        LightBlue = 91,
        LightCoral = 92,
        LightCyan = 93,
        LightGoldenrodYellow = 94,
        LightGray = 95,
        LightGreen = 96,
        LightPink = 97,
        LightSalmon = 98,
        LightSeaGreen = 99,
        LightSkyBlue = 100,
        LightSlateGray = 101,
        LightSteelBlue = 102,
        LightYellow = 103,
        Lime = 104,
        LimeGreen = 105,
        Linen = 106,
        Magenta = 107,
        Maroon = 108,
        MediumAquamarine = 109,
        MediumBlue = 110,
        MediumOrchid = 111,
        MediumPurple = 112,
        MediumSeaGreen = 113,
        MediumSlateBlue = 114,
        MediumSpringGreen = 115,
        MediumTurquoise = 116,
        MediumVioletRed = 117,
        MidnightBlue = 118,
        MintCream = 119,
        MistyRose = 120,
        Moccasin = 121,
        NavajoWhite = 122,
        Navy = 123,
        OldLace = 124,
        Olive = 125,
        OliveDrab = 126,
        Orange = 127,
        OrangeRed = 128,
        Orchid = 129,
        PaleGoldenrod = 130,
        PaleGreen = 131,
        PaleTurquoise = 132,
        PaleVioletRed = 133,
        PapayaWhip = 134,
        PeachPuff = 135,
        Peru = 136,
        Pink = 137,
        Plum = 138,
        PowderBlue = 139,
        Purple = 140,
        Red = 141,
        RosyBrown = 142,
        RoyalBlue = 143,
        SaddleBrown = 144,
        Salmon = 145,
        SandyBrown = 146,
        SeaGreen = 147,
        SeaShell = 148,
        Sienna = 149,
        Silver = 150,
        SkyBlue = 151,
        SlateBlue = 152,
        SlateGray = 153,
        Snow = 154,
        SpringGreen = 155,
        SteelBlue = 156,
        Tan = 157,
        Teal = 158,
        Thistle = 159,
        Tomato = 160,
        Turquoise = 161,
        Violet = 162,
        Wheat = 163,
        White = 164,
        WhiteSmoke = 165,
        Yellow = 166,
        YellowGreen = 167,
        ButtonFace = 168,
        ButtonHighlight = 169,
        ButtonShadow = 170,
        GradientActiveCaption = 171,
        GradientInactiveCaption = 172,
        MenuBar = 173,
        MenuHighlight = 174
    } // End enum AllKnownColors 


}

我可以在NetStandard 2.0下进行编译

如何:
System.CoreFX.Forms并将其转换为NetStandard 2.0。 然后添加System.Drawing.Common和System.Reflection.Emit。

采取AspNetCore.ReportingServices并添加

Microsoft.Win32.Registry
System.CodeDom
System.ComponentModel
System.ComponentModel.TypeConverter
System.Configuration.ConfigurationManager
System.Data.Common
System.Data.SqlClient
System.Drawing.Common 
System.IO.Packaging
System.Runtime.Serialization.Primitives
System.Security.Permissions

添加对System.CoreFX.Forms(NetStandard)的引用

从mono / corefx获​​取以下文件

AssemblyRef.cs (corefx System.Drawing)
ColorConverter.cs (corefx System.Drawing)
ColorConverterCommon.cs (corefx System.Drawing)
ColorTable.cs (corefx System.Drawing)
FontConverter.cs (mono System.Drawing.FontConverter.cs)
ImageFormatConverter.cs (mono System.Drawing.ImageFormatConverter.cs)
PaintValueEventArgs.cs (corefx System.Drawing.Design)
PointConverter.cs (corefx System.Drawing.Design)
SizeConverter.cs (corefx System.Drawing.Design)
UITypeEditor.cs  (corefx System.Drawing.Design "Primitives")
UITypeEditorEditStyle.cs  (corefx System.Drawing.Design "Primitives")

并为System.Web添加包装器类


namespace System.Web
{

    public class HttpRequest
    {
        public System.Collections.Specialized.NameValueCollection Headers { get; set; }
    }

    public class HttpResponse
    {
        public string ContentType { get; set; }
        public int StatusCode { get; set; }
    }

    public class HttpContext
    {
        // public HttpRequest Request;
        // public HttpRequest Response;

        public HttpRequest Request { get; set; }
        public HttpResponse Response { get; set; }


        public static HttpContext Current;
    }
}

并在新的netstandard 2.0项目中允许使用不安全的代码。

现在添加AssemblyInfo.cs与

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("AspNetCore.Reporting, PublicKey=00240000048000009400000006020000002400005253413100040000010001003736e45ce2a56cd06bc9ab2e7eeeeffd2533eaafbc1abc68561da0f512412bf1c7d2bd0c4422565a4f35818a205b4d54af1d0fef14fb8d7249bc37913e53a3313c2f26ca838849c5ef766082ed02db74e6459e77840dfe5eb01574aa0722876b2a9f714c5d03fbcea6e88345ccf55a87d57d9653a5913a826008b1d3ac557aab", AllInternalsVisible = true)]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("AspNetCore.Reporting", AllInternalsVisible = true)]

现在,它可以在NetStandard 2.0上编译。

@所有惊人的新闻:

我可以在Windows上与.NET Core一起使用!
100%NetStandard,0%NetFramework

HTML,PDF,Excel,Excel2007 +,Word,Word2007 +和tiff在包含varchars,int,tinyint2,位和计算列的57页表格报表中都可以正常工作。
除了RDL(有点有趣,但谁在乎),所有输出格式都可以工作。
我们最终会找到问题的,不是吗?

AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);
lr.AddDataSource("DataSet1", dt);

var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");

// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
// var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");

System.Console.WriteLine(rr.TotalPages);

// System.IO.File.WriteAllBytes(@"d:\foo.htm", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.css", rr.SecondaryStream);
// System.IO.File.WriteAllBytes(@"d:\foo.pdf", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.xls", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.xlsx", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.doc", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.docx", rr.MainStream);
// System.IO.File.WriteAllBytes(@"d:\foo.tiff", rr.MainStream);

// System.IO.File.WriteAllBytes(@"d:\foo.rpl", rr.MainStream); // BOOM 

还有更多的好消息:
WindowsBase(也称为WPF)仅用于System.IO.Packaging,它在.NET Core中可用。
现在这意味着,如果我们能够摆脱麻烦,那么在Linux / Mac上也没有主要的障碍!

现在有人迅速开始编写基于Web的RDL编辑器!
然后,我们也可以拥有“动态”(用户生成的)报告。
用于Linux的PostgreSQL-ReportingServices即将发布;)
(好的,在这种事情上有达摩克利斯的法律之剑,但如果我们能从中国获得它的话,那是拥有“更宽松”知识产权的……):)

好吧,也许那太邪恶了。
请改用Microsoft ReportingServices for Oracle / SAP!
或Cassandra / Spark的ReportingServices:咧着嘴笑:

@ amh1979
那里没有PowerPoint渲染器吗?
您是否从最新版本的reportviewer构建它? (SSRS 2017)
我在nuget上知道的最新版本:
https://www.nuget.org/packages/Microsoft.ReportingServices.ReportViewerControl.WebForms
(140.1000.523,10个月前)
https://www.nuget.org/packages/Microsoft.ReportingServices.ReportViewerControl.WinForms
(140.1000.523)
https://www.nuget.org/packages/Microsoft.SqlServer.Types
(14.0.314.76)

这是NetStandard的CoreFX WinForms实现:
https://github.com/ststeiger/System.CoreFX.Forms

请注意,自从我添加了一个额外的NetCore项目并将System.CoreFX.Forms重命名为System.NetStandard.Forms之后,如果加载嵌入式资源,可能会遇到困难。

这些文件可以在这里找到:

AssemblyRef.cs
ColorConverter.cs
ColorConverterCommon.cs
ColorTable.cs
FontConverter.cs
ImageFormatConverter.cs
PaintValueEventArgs.cs
PointConverter.cs
SizeConverter.cs
UITypeEditor.cs
UITypeEditorEditStyle.cs

@ amh1979
嗯,我知道,这不在Microsoft.ReportViewer.Common.dll中。
但是它在ReportServer目录中:
Microsoft.ReportingServices.PowerPointRendering.dll
对于CSV / XML / Atom:
Microsoft.ReportingServices.DataRendering.dll

C:\ Program Files \ Microsoft SQL Server报告服务\ SSRS \ ReportServer \ bin

@ALL :女士们,HTML渲染器正在.NET Core / NetStandard 2.0的Linux上工作!
WordOpenXML和ExcelOpenXML渲染器也是如此!
(未经图片/图形测试-仅文本和代码)

PDF渲染器在字体嵌入拼字游戏方面存在问题。
(Word / Excel-2003渲染器正在使用pinvokes,因此不起作用。)
如果使用Aspose Cells / Words评估版本,则可以将xlsx转换为xls,并将docx转换为doc。
您还可以从单词文件生成PDF:
soffice --headless --convert-to pdf filename.docx
(或再次使用aspose eval)
考虑一下,PPTX渲染器也应该很容易做到,因为它所做的只是从TIFF文件中拍摄图片并将每个tiff页面图像以jpg / png格式放置到pptx幻灯片上。
看起来图像渲染器是最难的事情。
或者,您可以使用wkhtmltoX并将每个HTML页面呈现为图像/ pdf。
不过,这可能有点慢。

惊人 !

HTML for report

@ALL :Atom / CSV / XML工作。 NULL渲染器也是如此。
在Linux上也是如此。

PowerPoint渲染仅适用于Windows-pinvokes

有趣的事实:那里似乎有一个JSON渲染器。
但是出于某种原因,这种废话只能在useSharedDataSetTableHandler的情况下起作用,无论这意味着什么

ParseDeviceInfo(deviceInfo);

if (!useSharedDataSetTableHandler)
{
    throw new ReportRenderingException(StringResources.rrJsonRenderOutputNotSupported);
}

任何有危险的人都知道如何使用JSON-renderer?

@ amh1979我尝试使用服务器报告,但为报告添加的参数似乎未在LoadReport中持久保存到服务器。 您是否有可能进行设置,以便将其发送到下一个版本中的服务器?

@ststeiger@ amh1979 ,这方面的
我一直在尝试访问nuget软件包说明中链接的网站(http://www.amhx.org/),但它总是使我超时。

@DavidHayesCoding
这是我感兴趣的AspNetCore.Reporting.LocalReport的测试代码:
注意:
渲染类型Rpl,RGDI,Atom,Xml,Json,Csv,null,pptx
您将无法使用,因为它们不在amh1979的大会中。
(它们是SSRS的一部分,但不存在于ReportViewer可重新分发的文件中)

另请注意,共享数据源(* .rds)必须与* .rdl位于同一目录中,否则,您将在LocalReport.Execute上获得空引用异常。

如有其他疑问:
https://github.com/icsharpcode/ILSpy/releases/tag/v4.0-beta2
(注意:在正确的代码中,您需要在使用完数据表后处置它)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace NetCoreReporting
{


    public class Program
    {


        public static void Main(string[] args)
        {
            System.Data.SqlClient.SqlConnectionStringBuilder csb = new System.Data.SqlClient.SqlConnectionStringBuilder();
            csb.InitialCatalog = "TestDB";

            if ("COMPANY_NAME".Equals(System.Environment.UserDomainName, System.StringComparison.InvariantCultureIgnoreCase))
                csb.DataSource = System.Environment.MachineName + @"\SQLEXPRESS";
            else
                csb.DataSource = System.Environment.MachineName;

            if(System.Environment.OSVersion.Platform == System.PlatformID.Unix)
                csb.IntegratedSecurity = false;
            else
                csb.IntegratedSecurity = true;

            if (!csb.IntegratedSecurity)
            {
                csb.UserID = TestPlotly.SecretManager.GetSecret<string>("DefaultDbUser");
                csb.Password = TestPlotly.SecretManager.GetSecret<string>("DefaultDbPassword");
            }



            string sql = "SELECT * FROM T_Sites";
            // sql = "SELECT * FROM T_Users";

            System.Data.DataTable dt = new System.Data.DataTable();

            using (System.Data.Common.DbDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, csb.ConnectionString))
            {
                da.Fill(dt);
            }

            string fn = "wwwroot/Report1.rdl";
            fn = "wwwroot/Report2.rdl";

            AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);


            System.Collections.Generic.Dictionary<string, string> parameters = 
                new System.Collections.Generic.Dictionary<string, string>();

            // parameters.Add("in_logo", "base64");

            lr.AddDataSource("DataSet1", dt); // DataSet1 is the name of the DataSet in the report




            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 1, null, "");

            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Atom, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Xml, 1, null, "");
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Json, 1, null, "");// KABOOM 
            // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Csv, 1, null, "");

            var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pptx, 1, parameters, "");

            System.Console.WriteLine(rr.TotalPages);


            string dir = @"d:\";
            if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
                dir = "/opt/";

            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.css"), rr.SecondaryStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pdf"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xls"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xlsx"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.doc"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.docx"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.tiff"), rr.MainStream);

            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.atom.xml"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xml"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.json"), rr.MainStream);
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.csv"), rr.MainStream);

            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.rpl"), rr.MainStream); // BOOM 
            // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
            System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pptx"), rr.MainStream);

            BuildWebHost(args).Run();
        }


        public static IWebHost BuildWebHost(string[] args)
        { 
            return WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
        }


    }


}

我是否可以建议发布大量的代码和长度注释是跟踪此问题的一种真正难以理解和阅读的方式?

我可以看到很多活动,很多代码,但是对于最近(看似出色)的开发情况,确实没有什么明智的选择。

我可以建议在这里保持整洁,并使用另一个仓库/适当的工具来共享代码吗? 是否可以在此处共享简单明了的状态更新?

@kierenj一样,我认为代码清单作为帖子很难遵循。 放置一个github,然后共享一个链接。 看看这个仓库的管理员是否想做一些分支等...

@kierenj @figuerres :我可以接受,但是如果您在未事先征得许可的情况下发布了大量反编译的Microsoft代码,则可能会冒昧地跨过他们可能想对此做些事情的地方...

iii。 发行限制。 你不可以
•分发可分发代码以在Windows平台以外的平台上运行;
•以源代码形式公开或分发代码; 要么
•其他人有权对其进行修改。

@ststeiger
您可以在此处与该仓库一起创建一个分支,并将代码放入该分支中。
然后他们就知道了,等等...

@figuerres :我在gitlab上进行了回购,其中有一个免费的私人存储库。

@MaximRouiller
我将拥有一个大致在ASP.NET Core下工作的ReportViewer(本地报告)版本。
大约有75%的系统甚至可以在Microsoft发布了SQL-Server的Linux下运行。
在Linux下工作的部件很可能也在MacOS下工作。

但是,此版本的ReportViewer基于以下代码
https://www.nuget.org/packages/AspNetCore.Reporting
这似乎是基于
https://www.nuget.org/packages/Microsoft.ReportingServices.ReportViewerControl.WebForms
在此许可下
http://go.microsoft.com/fwlink/?LinkId=826162

该许可证不允许
•分发可分发代码以在Windows平台以外的平台上运行;
•以源代码形式公开或分发代码; 要么
•其他人有权对其进行修改。
•解决软件中的任何技术限制;
•>不允许进行逆向工程<

我想(尚未公开)在github上的社区(尚未确定的位置)上与该社区共享该代码,以改进代码并找出任何可能的错误,以将ReportViewer引入.NET Core。
但是,我不愿意单方面考虑ReportViewerControl.WebForms的当前许可采取这样的步骤。

我认为自该许可证首次写入/最后更新以来,已经发生了很多变化。
例如,当结果仅在Windows平台上有效时,为.NET Core发布ReportViewer几乎没有意义-还考虑到Microsoft已发布Linux的SQL Server,这意味着在某个时间点,SSRS必须仍然按照。

并且鉴于ASP.NET-Core不实现WebForms,从ReportViewer-WebForms到ReportViewer-NetCore的更改仍然是一个重大更改。

您能否离散地问一问这些权力,如果考虑到情况,它们是否为这种努力提供了开绿灯-顺便说一句,这也可以节省他们的时间和人力,并且与.NET-Core / NetStandard 2.0。

自.NET-Core发布以来已经有2年多的时间了,对于广泛的报告,仍然没有解决方案。 现在该纠正了。
如果我们一起做,我们都会更快更好。

http://go.microsoft.com/fwlink/?LinkId=826162
我担心的是
如果没有,我将从NuGet中取消列出软件包。

@ALL
因此,XLS / DOC-Renderer现在可以在Linux和Windows上运行。
现在85%的人在Linux上工作。

看来我们只有3个针对PDFWriter的WinAPI调用和13个针对ImageRenderer / Graphics的WinAPI调用。
我认为PdfWriter本身可能很容易。

@ststeiger,您好

尚未完全实现-它多次调用GDI +和usp10.dll,主要是为了获取字体信息。
它还传递GDI +指针,并且没有简单的替代方法,因为mono libgdi +选择了不同的方式(有充分的理由)。

通过阅读Wine的C源代码,我已经能够在C#中重写函数GetFontData,但是我需要freetype才能获取TrueType字体信息(葡萄酒也使用FreeType)。
SixLabors.Fonts和LayoutFarm尚不存在(很大距离)。
这里:
https://gist.github.com/ststeiger/273341aebd29009f2b272b822b69563f

另外,我用freetype替换了text-measurements

现在,我需要用自定义类替换每个GDI设备句柄。
然后,该类必须包含字体/图形/ freetype-face /句柄信息等,因此我不需要重新编写渲染器。

完成此操作后,我需要再次查看葡萄酒,以实现纸张到世界和世界到纸张的转换。
然后应该完成。
我认为纸张到世界和纸张到世界的转换可能已经在System.Drawing.Graphics中。
看起来部分代码曾经是使用.NET Framwork 1.0编写的。

另外,我仍然需要以某种方式在.NET字体和freetype字体之间进行映射。

大家好@ALL和@ststeiger
关于:

@ALL
因此,XLS / DOC-Renderer现在可以在Linux和Windows上运行。
现在85%的人在Linux上工作。

Office Open XML

老实说,我认为最好使用更新的XML文档,然后根本不需要OLE形式。
好吧,如果有人仍在使用真的很老的Office应用程序,那么对于后兼容来说就不太好。 但是Office Open XML大约在2002年至2006年问世,因此过去10年中使用word或excel的任何人都可以使用docx和xlsx文件格式。
只是我的想法...

只是为了我们不要误解我们:
当然,OpenXml Excel渲染器也可以正常工作。

我只是说XLS / DOC也可以工作。
现在,是否应该公开XLS / DOC,或者是否可以安全删除XLS / DOC是另一个问题。 可能仍然有一些旧程序无法与XLSX一起使用。

例如,UBS仍使用COBOL程序。
还有其他各种。
因此,以防万一,最好让XLS功能再使用一会儿。

@RaymondHuy
如果Azure阻止了GDI +功能,System.Drawing.Common是否可以正常工作?
还是这仅适用于框架外部的DllImport调用?

嗯,只是用谷歌搜索。
看起来System.Drawing库在Azure云服务(基本上只是一个VM)中可用,但在Azure Web App(基本上是共享托管?)中不可用。
这可能是个问题。
因此,一旦它在Linux上运行,我们需要稍后用SixLabors.ImageSharp替换任何System.Drawing,以使其在Azure Web App上运行。

这将花费时间和精力。
@RaymondHuy
您可以检查FreeType(SharpFont包装器)是否在Azure上工作吗?
https://github.com/Robmaister/SharpFont

注意:
在x64-Windows上,您需要使用以下命令替换FT_Long和FT_ULong的using子句

#if WINDOWS
    using FT_Long = System.Int32;
    using FT_ULong = System.UInt32;    
#else // Linux, MacOS
    using FT_Long = System.IntPtr;
    using FT_ULong = System.UIntPtr;
#endif

因为修补的freetype dll在x64-Windows上不起作用。

这是我的方法:
https://gist.github.com/ststeiger/9e2eb98e29a3c987aca739045af1d2ce

(注意:在构建选项中定义WINDOWS)

带有一些测试代码:

SharpFont.Native.Init();

SharpFont.Library lib = new SharpFont.Library();

string font = @"C:\Windows\Fonts\tahoma.ttf";
if(System.Environment.OSVersion.Platform == System.PlatformID.Unix)
    font = "/usr/share/wine/fonts/tahoma.ttf";

SharpFont.Face fontFace = new SharpFont.Face(lib, font);


float size = 12;
if (fontFace!= null)
    // fontFace.SetCharSize(0, size, 0, 96);
    fontFace.SetCharSize(size, size, 96, 96);

System.Console.WriteLine(fontFace.Size.Metrics.Ascender.ToDouble());

如果未应用WINDOWS校正,则fontFace.Size.Metrics.Ascender将产生异常。

当我尝试使用.rdlc文件时,出现异常
'AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.DataRegionExprHost(TMemberType,TCellType).m_memberTreeHostsRemotable'在此上下文中不可访问,因为它是'Friend'。 在localreport.Execute()中
请帮我

        string sql = "SELECT * FROM employee";
        // sql = "SELECT * FROM T_Users";

        System.Data.DataTable dt = new System.Data.DataTable();

        using (System.Data.Common.DbDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, csb.ConnectionString))
        {
            da.Fill(dt);
        }

        string fn = "wwwroot/Report1.rdl";
        fn = "wwwroot/InOutTab31.rdlc";

        AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);


        System.Collections.Generic.Dictionary<string, string> parameters =
            new System.Collections.Generic.Dictionary<string, string>();
        parameters["TEN_ID"]="45";
        parameters["START_DATE"]="2018";
        parameters["END_DATE"]= "2018";

        // parameters.Add("in_logo", "base64");

        lr.AddDataSource("DsDayStatusTab31", dt); // DataSet1 is the name of the DataSet in the report




        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 1, null, "");

        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Atom, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Xml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Json, 1, null, "");// KABOOM 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Csv, 1, null, "");

        var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, parameters, "");

        System.Console.WriteLine(rr.TotalPages);


        string dir = @"d:\";
        if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
            dir = "/opt/";

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.css"), rr.SecondaryStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pdf"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xls"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xlsx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.doc"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.docx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.tiff"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.atom.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.json"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.csv"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.rpl"), rr.MainStream); // BOOM 
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pptx"), rr.MainStream);

        BuildWebHost(args).Run();

似乎您对嵌入式VB表达式有疑问。
无论如何,存在多个问题。

在Microsoft.VisualBasic1 \ VBCodeGenerator.cs中
UseShellExecute需要设置为false。

System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(cmd)
{
    WorkingDirectory = currentDir,
    RedirectStandardOutput = true,
    RedirectStandardInput = true,
    UseShellExecute = false  // <== or else it can't redirect output
};

如果为netstandard编译,则FromFileBatch必须替换为roslyn(CodeDom提供程序无法针对netstandard编译-如果使用VB表达式(例如,在参数中),则是有趣的异常)


        protected override System.CodeDom.Compiler.CompilerResults FromFileBatch(System.CodeDom.Compiler.CompilerParameters options, string[] fileNames)
        {

#if NETSTANDARD2_0
            return NetStandardFromFileBatch(options, fileNames);
#else
            return OldFromFileBatch(options, fileNames);
#endif
        }




#if NETSTANDARD2_0         



        protected System.CodeDom.Compiler.CompilerResults NetStandardFromFileBatch(System.CodeDom.Compiler.CompilerParameters options, string[] fileNames)
        {
            //// C:\Program Files\dotnet\sdk\2.0.0\Roslyn

            //string sysver = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion();
            //System.Console.WriteLine(sysver);


            //string pf64 = System.Environment.ExpandEnvironmentVariables("%ProgramW6432%");
            //string pf32 = System.Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%");
            //string pf = pf32;

            //if (System.IntPtr.Size * 8 == 64)
            //    pf = pf64;

            //// compilerDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles);
            ////compilerDirectory = System.IO.Path.Combine(compilerDirectory, "dotnet", "sdk", "2.0.0", "Roslyn");
            //compilerDirectory = System.IO.Path.Combine(pf32, "MSBuild", "14.0", "Bin");
            //if (System.IntPtr.Size * 8 == 64)
            //    compilerDirectory = System.IO.Path.Combine(compilerDirectory, "amd64");

            string assemblyName = System.IO.Path.GetFileNameWithoutExtension(options.OutputAssembly);

            Microsoft.CodeAnalysis.SyntaxTree[] syntaxTrees = new Microsoft.CodeAnalysis.SyntaxTree[fileNames.Length];

            for (int i = 0; i < fileNames.Length; ++i)
            {
                string fileContent = System.IO.File.ReadAllText(fileNames[i], System.Text.Encoding.UTF8);

                Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions op = null;

                // ERR_EncodinglessSyntaxTree = 37236 - Encoding must be specified... 
                syntaxTrees[i] = Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.ParseText(
                    fileContent, op, fileNames[i], System.Text.Encoding.UTF8
                );

            }

            Microsoft.CodeAnalysis.MetadataReference[] references =
                new Microsoft.CodeAnalysis.MetadataReference[options.ReferencedAssemblies.Count];

            for (int i = 0; i < references.Length; ++i)
            {
                references[i] = Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(
                    options.ReferencedAssemblies[i]
                );
            }



            Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions co =
                new Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions
            (
                Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary
            );

            co.WithOptionStrict(Microsoft.CodeAnalysis.VisualBasic.OptionStrict.Off);
            co.WithOptionExplicit(false);
            co.WithOptionInfer(true);

            Microsoft.CodeAnalysis.Compilation compilation = Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilation.Create(
                assemblyName,
                syntaxTrees,
                references,
                co
            );


            System.CodeDom.Compiler.CompilerResults compilerResults = new System.CodeDom.Compiler.CompilerResults(options.TempFiles);

            compilerResults.NativeCompilerReturnValue = -1;

            // using (var dllStream = new System.IO.MemoryStream())
            using (System.IO.FileStream dllStream = System.IO.File.Create(options.OutputAssembly))
            {
                using (System.IO.MemoryStream pdbStream = new System.IO.MemoryStream())
                {
                    Microsoft.CodeAnalysis.Emit.EmitResult emitResult = compilation.Emit(dllStream, pdbStream);
                    if (!emitResult.Success)
                    {

                        foreach (Microsoft.CodeAnalysis.Diagnostic diagnostic in emitResult.Diagnostics)
                        {
                            // options.TreatWarningsAsErrors
                            if (diagnostic.IsWarningAsError || diagnostic.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error)
                            {
                                string errorNumber = diagnostic.Id;
                                string errorMessage = diagnostic.GetMessage();

                                string message = $"{errorNumber}: {errorMessage};";
                                string fileName = diagnostic.Location.SourceTree.FilePath;

                                Microsoft.CodeAnalysis.FileLinePositionSpan lineSpan = diagnostic.Location.GetLineSpan();
                                string codeInQuestion = lineSpan.Path;
                                int line = lineSpan.StartLinePosition.Line;
                                int col = lineSpan.StartLinePosition.Character;

                                compilerResults.Errors.Add(
                                    new System.CodeDom.Compiler.CompilerError(fileName, line, col, errorNumber, errorMessage)
                                );
                            } // End if 

                        } // Next diagnostic 

                        // emitResult.Diagnostics
                        // CheckCompilationResult(emitResult);
                    }
                    else
                    {
                        compilerResults.PathToAssembly = options.OutputAssembly;
                        compilerResults.NativeCompilerReturnValue = 0;
                    }
                }
            }

            // compilerResults.CompiledAssembly = System.Reflection.Assembly.Load(array3, null);

            return compilerResults;
        }
#endif

https://github.com/aspnet/RoslynCodeDomProvider中有RoslynCodeDomProviders,但无论如何它们都在后台使用Roslyn。 并使用“ C:\ WINDOWS \ Microsoft.NET \ Framework进行相对硬编码\\ vbc.exe“绝对不是一个好主意。

现在,我可以使用完整的HTML4,HTML5和MHTML渲染器。
不只是分页的。

嗨,我正在使用[https://www.nuget.org/packages/AspNetCore.Reporting],它在本地IIS中完美运行。
但是,一旦将其部署在Windows Server 2012 R2中,就会遇到问题。

错误日志。

失败:Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware [1]
执行请求时发生未处理的异常。
AspNetCore.Reporting.LocalProcessingException:本地报表处理期间发生错误。;报表'D:\ Apps \ BillingApproval \ ReportFiles \ ReleaseProcess.rdl'的定义无效。
编译表达式时发生意外错误。 本机编译器返回值: -1073741819'. ---> AspNetCore.Reporting.DefinitionInvalidException: The definition of the report 'D:\Apps\BillingApproval\ReportFiles\ReleaseProcess.rdl' is invalid. An unexpected error occurred while compiling expressions. Native compiler return value: -1073741819'。 ---> AspNetCore.ReportingServices.ReportProcessing.ReportPublishingException:编译表达式时发生意外错误。 本机编译器返回值: -1073741819'. at AspNetCore.ReportingServices.ReportPublishing.ReportPublishing.InternalCreateIntermediateFormat(Stream definitionStream, String& description, String& language, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash) at AspNetCore.ReportingServices.ReportPublishing.ReportPublishing.CreateIntermediateFormat(Byte[] definition, String& description, String& language, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash) at AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CompileOdpReport(PublishingContext reportPublishingContext, PublishingErrorContext errorContext, String& reportDescription, String& reportLanguage, ParameterInfoCollection& parameters, DataSourceInfoCollection& dataSources, DataSetInfoCollection& sharedDataSetReferences, UserLocationFlags& userReferenceLocation, ArrayList& dataSetsName, Boolean& hasExternalImages, Boolean& hasHyperlinks, Byte[]& dataSetsHash) at AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CreateIntermediateFormat(PublishingContext reportPublishingContext) at AspNetCore.Reporting.ReportCompiler.CompileReport(ICatalogItemContext context, Byte[] reportDefinition, Boolean generateExpressionHostWithRefusedPermissions, ControlSnapshot& snapshot) --- End of inner exception stack trace --- at AspNetCore.Reporting.ReportCompiler.CompileReport(ICatalogItemContext context, Byte[] reportDefinition, Boolean generateExpressionHostWithRefusedPermissions, ControlSnapshot& snapshot) at AspNetCore.Reporting.LocalService.GetCompiledReport(PreviewItemContext itemContext, Boolean rebuild, ControlSnapshot& snapshot) at AspNetCore.Reporting.LocalService.CompileReport() at AspNetCore.Reporting.LocalService.AspNetCore.Reporting.ILocalProcessingHost.CompileReport() at AspNetCore.Reporting.InternalLocalReport.EnsureExecutionSession() --- End of inner exception stack trace --- at AspNetCore.Reporting.InternalLocalReport.EnsureExecutionSession() at AspNetCore.Reporting.InternalLocalReport.SetParameters(IEnumerable 1个参数)
在AspNetCore.Reporting.Report.SetParameters(ReportParameter参数)
在AspNetCore.Reporting.LocalReport.Execute(RenderType renderType,Int32 pageIndex,字典2 parameters, String findString) at BA.UI.WebV2.Extension.AspNetCoreReportingExtension.ExecuteToMemoryStreamResult(LocalReport localreport, RenderType rendertype, Int32 index, Dictionary 2个参数,字符串searchString)在D:\ Projects \ Approval \ Main \ BA.UI.WebV2 \ Extension \ AspNetCoreReportingExtension.cs: 27行
在BA.UI.WebV2.Controllers.ReportsController.ReleaseProcessToPDF(DateTime from,DateTime to)在D:\ Projects \ Approval \ Main \ BA.UI.WebV2 \ Controllers \ ReportsController.cs:第65行
在lambda_method(Closure,Object,Object [])
在Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper映射器,ObjectMethodExecutor执行器,对象控制器,Object []参数)
在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext上下文)
在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(状态和下一个,范围和范围,对象和状态,布尔值和isCompleted)处
在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext上下文)
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(状态和下一个,范围和范围,对象和状态,布尔值和isCompleted)处
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
在Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
在Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext上下文)
在Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext上下文)
在Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext上下文)

@jfmjason :由CodeDom代码编译器(.NET 4.0)尝试在ExprHostCompiler的临时路径中编译一些文件时引起。 它希望使用.NET 4.0提供程序来编译NetStandard / NetCore程序集。 那不行当它尝试编译那些文件时,csc.exe静默失败,返回值为-1073741819。
由于您无法使用.NET 4.0编译器来编译.NET Core代码,因此需要使用RoslynCompilers,它不在System.CodeDom中。 我上面的NetStandardFromFileBatch完全解决了该问题(如果为NetFramework 4编译则使用CodeDom)。

但是,请注意,.NET Core中的VB运行时受到严重限制。
基本上,.NET Core并不真正支持VB.NET。

如果您在Microsoft.VisualBasic.Strings中查看基本的VB内容,例如50个左右的VB字符串函数,例如Replace,Trim,AscW,ChrW,LCase,Len,Mid,则.NET Core 2.0恰好支持其中的2个, AscW和ChrW ...

如果您查看github上的当前源代码,现在会看到它们在那里,但是所有存根都为null的存根。
https://github.com/dotnet/corefx/blob/master/src/Microsoft.VisualBasic/ref/Microsoft.VisualBasic.cs

因此,除此之外,您可能还需要稍微修改报表中的VB代码-支持.NET Core和NetFramework。

所以@ALL :这是一个主意:
如果您希望报告的代码在.NET Core上运行且无需修改,请开始在Microsoft.VisualBasic.cs中实现字符串函数。
或删除VB运行时特定的东西,并尝试使用C#提供的类和成员函数,例如string.Length代替Len,IndexOf代替InStr,Subtring代替Mid,“ BLA” .ToLower()代替LCase (“ BLA”)等。

此外,一般而言,不仅在.NET Core中,VB代码在可空语法?方面存在问题。
因此,如果需要声明例如函数的返回值,请使用System.Nullable(Of Double)而不是Double?。

NuGets:
Microsoft.CodeAnalysis.Common,Microsoft.CodeAnalysis.CSharp,Microsoft.CodeAnalysis.VisualBasic

另外,您需要在ExprHostCompiler.cs中更改程序集引用:
(AspNetCore.ReportingServices.RdlExpressions \ ExprHostCompiler.cs)

   private static System.Reflection.Assembly GetNetStdAssembly()
        {
            System.Reflection.Assembly nsAssembly = null;

            System.Reflection.AssemblyName[] asms = typeof(Microsoft.VisualBasic.Constants).Assembly.GetReferencedAssemblies();


            foreach (System.Reflection.AssemblyName asm in asms)
            {
                if (asm.FullName.StartsWith("netstandard,", System.StringComparison.OrdinalIgnoreCase))
                {
                    nsAssembly = System.Reflection.Assembly.Load(asm.FullName);
                    break;
                }
            }

            return nsAssembly;


            //System.Reflection.Assembly[] asms = System.AppDomain.CurrentDomain.GetAssemblies();
            //
            //foreach (System.Reflection.Assembly asm in asms)
            //{
            //    if (asm.FullName.StartsWith("netstandard,", System.StringComparison.OrdinalIgnoreCase))
            //    {
            //        nsAssembly = asm;
            //        break;
            //    }
            //}

            // return nsAssembly;
        }



        private byte[] InternalCompile(System.AppDomain compilationTempAppDomain, bool refusePermissions)
        {
            if (m_builder.HasExpressions)
            {
                System.CodeDom.Compiler.CompilerParameters compilerParameters = new System.CodeDom.Compiler.CompilerParameters();
                compilerParameters.OutputAssembly = System.IO.Path.Combine(System.IO.Path.GetTempPath(), m_expressionHostAssemblyHolder.ExprHostAssemblyName, "ExpressionHost.dll");
                compilerParameters.TempFiles = new System.CodeDom.Compiler.TempFileCollection(System.IO.Path.GetDirectoryName(compilerParameters.OutputAssembly));
                compilerParameters.GenerateExecutable = false;
                compilerParameters.GenerateInMemory = false;
                compilerParameters.IncludeDebugInformation = false;

                compilerParameters.ReferencedAssemblies.Add(typeof(AspNetCore.Reporting.InternalLocalReport).Assembly.Location);

                // Real reportServer
                // compilerParameters.ReferencedAssemblies.Add("System.dll");
                // compilerParameters.ReferencedAssemblies.Add(typeof(AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.ReportObjectModelProxy).Assembly.Location);
                // compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.SqlServer.Types.SqlGeography).Assembly.Location);

#if NETSTANDARD2_0

                // Assemblies: mscorlib.dll, netstandard.dll, System.Threading.Thread.dll
                // System.Threading.Thread.dll, not netstandard.dll ...
                //// compilerParameters.ReferencedAssemblies.Add(typeof(System.LocalDataStoreSlot).Assembly.Location);

                // compilerParameters.ReferencedAssemblies.Add(System.Linq.Enumerable.FirstOrDefault(System.Linq.Enumerable.Where(System.AppDomain.CurrentDomain.GetAssemblies(), (System.Reflection.Assembly t) => t.FullName.Contains("netstandard,"))).Location);

                // netstandard.dll
                compilerParameters.ReferencedAssemblies.Add(GetNetStdAssembly().Location);

                // System.Private.CoreLib.dll
                compilerParameters.ReferencedAssemblies.Add(typeof(System.MarshalByRefObject).Assembly.Location);

                // System.Runtime.dll
                compilerParameters.ReferencedAssemblies.Add(typeof(System.IO.FileAttributes).Assembly.Location);

                // Microsoft.VisualBasic.dll
                compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.VisualBasic.Constants).Assembly.Location);

                //compilerParameters.ReferencedAssemblies.Add(typeof(string).Assembly.Location);
                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Uri).Assembly.Location);

                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Drawing.RectangleF).Assembly.Location);
                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Drawing.Graphics).Assembly.Location);

                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Data.Common.DbCommand).Assembly.Location);
                //compilerParameters.ReferencedAssemblies.Add(typeof(System.Data.SqlClient.SqlCommand).Assembly.Location);

                //// compilerParameters.ReferencedAssemblies.Add(typeof(System.LocalDataStoreSlot).Assembly.Location);
#else

                // mscorlib
                compilerParameters.ReferencedAssemblies.Add(typeof(string).Assembly.Location); 

                // System.Core
                // Already contains reference to System.Core
                // compilerParameters.ReferencedAssemblies.Add(typeof(System.IO.Pipes.PipeSecurity).Assembly.Location);

                // Microsoft.CSharp
                // compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException).Assembly.Location); 

                // Microsoft.VisualBasic.Constants
                compilerParameters.ReferencedAssemblies.Add(typeof(Microsoft.VisualBasic.Constants).Assembly.Location); 

                // System
                // Already contains reference to System
                // compilerParameters.ReferencedAssemblies.Add(typeof(System.Uri).Assembly.Location); 
                // Already contains reference to System.Drawing
                // compilerParameters.ReferencedAssemblies.Add(typeof(System.Drawing.Graphics).Assembly.Location);
                // Already contains reference to System.Data 
                // compilerParameters.ReferencedAssemblies.Add(typeof(System.Data.DataTable).Assembly.Location);
#endif

                compilerParameters.CompilerOptions += m_langParser.GetCompilerArguments();

@ amh1979 :我还没有看过,但是在分页查看器中,报表中的图像是否出现在分页HTML渲染中?
因为当我从ReportServer中获取html4&5完整渲染器时,图像似乎被委托给ReportingServices的axd或ashx处理程序。 它们出现在MHT版本中。

它们可能应该更改为url(“ data:image / png; base64,SOME_BASE64_IMAGE”); 而是使它们在HTML中内联。
也就是说,如果他们要去一个非外部链接。
没有测试这是否也会影响观看者。

@ststeiger

感谢您的答复。 我不知道为什么当我在本地IIS中发布Web应用程序的发布版本(.net core 2.1)时,它为什么能完美工作。

可能是因为它在本地工作,因为您在本地安装了.NET Framework。
或者,因为您的本地Web服务器未处于集成模式,而是在另一个用户下运行,或者它访问了另一个逻辑路径,应用程序池设置,安全设置,程序集重定向等。
此外,还有ServicePack,CumulativeUpdates和其他令人兴奋的“功能”。

做了一个小型测试应用程序。
在Win10下添加System.Drawing.Common之后,它可以正常工作。
在Ubuntu 16.04上运行会导致错误。
AspNetCore.Reporting.LocalProcessingException:本地报表处理期间发生错误。;报表'/opt/testReportViewer/bin/Debug/netcoreapp2.1/Reports/Report1.rdlc'的定义无效。
报表处理中发生意外错误。
无法加载共享库“ kernel32.dll”或其依赖项之一。 为了帮助诊断加载问题,请考虑设置LD_DEBUG环境变量:libkernel32.dll:无法打开共享对象文件:无此类文件或目录---> AspNetCore.Reporting.DefinitionInvalidException:报告的定义'/ opt / testReportViewer /bin/Debug/netcoreapp2.1/Reports/Report1.rdlc'无效。
报表处理中发生意外错误。
无法加载共享库“ kernel32.dll”或其依赖项之一。 为了帮助诊断加载问题,请考虑设置LD_DEBUG环境变量:libkernel32.dll:无法打开共享对象文件:无此类文件或目录---> AspNetCore.ReportingServices.ReportProcessing.ReportProcessingException:报表处理中发生意外错误。
无法加载共享库“ kernel32.dll”或其依赖项之一。 为了帮助诊断加载问题,请考虑设置LD_DEBUG环境变量:libkernel32.dll:无法打开共享库文件:没有这样的文件或目录---> System.DllNotFoundException:无法加载共享库“ kernel32.dll”或一个它的依赖关系。 为了帮助诊断加载问题,请考虑设置LD_DEBUG环境变量:libkernel32.dll:无法打开共享对象文件:没有这样的文件或目录
在AspNetCore.ReportingServices.ReportPublishing.ReportPublishing.InternalCreateIntermediateFormat(Stream definitionStream,String&描述,String&语言,ParameterInfoCollection&参数,DataSourceInfoCollection&dataSources,DataSetInfoCollection&sharedDataSetReferences,UserLocationFlags&userReferenceLocation,ArrayList&dataSetsName,Boolean&hasHexternalImages,
在AspNetCore.ReportingServices.ReportPublishing.ReportPublishing.CreateIntermediateFormat(Byte []定义,字符串和描述,字符串和语言,ParameterInfoCollection&参数,DataSourceInfoCollection&数据源,DataSetInfoCollection&sharedDataSetReferences,UserLocationFlags&userReferenceLocation,ArrayList&dataSetsName,Boolean&hasHternalss,]
在AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CompileOdpReport(PublishingContext reportPublishingContext,PublishingErrorContext errorContext,String&reportDescription,String&reportLanguage,ParameterInfoCollection&parameters,DataSourceInfoCollection&dataSources,DataSetInfoCollection&sharedDataSetReferences,UserLocationFlags&dataRes yy]
在AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CreateIntermediateFormat(PublishingContext reportPublishingContext)
---内部异常堆栈跟踪的结尾---
在AspNetCore.ReportingServices.ReportProcessing.ReportProcessing.CreateIntermediateFormat(PublishingContext reportPublishingContext)
在AspNetCore.Reporting.ReportCompiler.CompileReport(ICatalogItemContext上下文,Byte [] reportDefinition,布尔值generateExpressionHostWithRefusedPermissions,ControlSnapshot和快照)
---内部异常堆栈跟踪的结尾---
在AspNetCore.Reporting.ReportCompiler.CompileReport(ICatalogItemContext上下文,Byte [] reportDefinition,布尔值generateExpressionHostWithRefusedPermissions,ControlSnapshot和快照)
在AspNetCore.Reporting.LocalService.GetCompiledReport(PreviewItemContext itemContext,布尔值重建,ControlSnapshot和快照)
在AspNetCore.Reporting.LocalService.CompileReport()
在AspNetCore.Reporting.LocalService.AspNetCore.Reporting.ILocalProcessingHost.CompileReport()
在AspNetCore.Reporting.InternalLocalReport.EnsureExecutionSession()
---内部异常堆栈跟踪的结尾---

@ststeiger AspNetCore.Reporting库上有任何新闻吗? 几天以来,我一直在寻找一种从.NET Core上的RDL文件创建PDF的解决方案,而我发现的唯一解决方案是AspNetCore.Reporting,后来我发现它只能在Windows上使用,并且您在此处进行的更改和报告的更改都非常吸引人。 ,这还因为我在使用子报表时遇到了很多麻烦,并且在没有源的情况下也无法调试AspNetCore.Reporting :) ...我非常有兴趣帮助您使用该库来改善缺失的部分(并最终能够对其进行调试...)

@OkunevPY :这可能是由用于安全地存储数据源数据的内存管理功能之一引起的。 在Linux上,我只是将其关闭-存储未加密的数据。 然后就可以了,尽管不安全。 不过,您必须在ReportViewer代码中执行此操作。 生产级代码必须实现加密/解密方法,这并不困难-但我宁愿先让所有功能正常工作,

@zillemarco;
创建PDF尚不起作用(仅适用于Windows)。
另外,如果您创建使用该反向工程dll部署的任何应用程序,从技术上讲,您所做的都是违法的。

如果您需要在Linux上生成PDF,建议您使用wkHtmlToPdf从HTML生成PDF。
这是一个.NET-Core变体:
https://github.com/ststeiger/libWkHtml2X
仅使用可执行变体(通过输入/输出流的wkhtmltopdf.exe,wkhtmltoimage.exe)
libWkHtmlToX.ProcessManager(opts)
因为wkhtmltox.dll在多线程方案中不起作用,而且我的C#接口目前还没有完全没有错误。

一些用法示例(converter.telerik.com转换为C#):

  • SVG转换为PDF:
Dim pngBytes As Byte() = Nothing
Dim paper_maxWidth As Double = 1024 ' pixel
Dim paper_maxHeight As Double = 768 ' pixel
Dim svgInfo As cSvgInfo = Portal_Convert.wkHtmlHelper.SvgToPaperSize(svg, paper_maxWidth, paper_maxHeight, False)

Dim opts As New libWkHtmlToX.WkHtmlToImageCommandLineOptions()
opts.ExecutableDirectory = Portal_Convert.wkHtmlHelper.GetWkHtmlToXPath()

opts.DisableSmartWidth = True
opts.ScreenWidth = System.Math.Ceiling(svgInfo.NewWidth)
opts.ScreenHeight = System.Math.Ceiling(svgInfo.NewHeight)

' svgInfo.HTML = System.IO.File.ReadAllText(System.Web.Hosting.HostingEnvironment.MapPath("~/External/1506414857353.svg"), System.Text.Encoding.UTF8)

Using p As New libWkHtmlToX.ProcessManager(opts)
    p.Start()
    p.WriteStandardInput(svgInfo.HTML)
    pngBytes = p.ReadOutputStream()

    Dim b As Boolean = p.WaitForExit(5000)
End Using ' p 
  • HTML转换为PDF:
        Dim opts As New libWkHtmlToX.WkHtmlToPdfCommandLineOptions()
        opts.ExecutableDirectory = Portal_Convert.wkHtmlHelper.GetWkHtmlToXPath()

        ' Dim measure As String = value.Replace(Number.ToString(), "")

        'Dim dblWidth As Double = Double.Parse(System.Text.RegularExpressions.Regex.Match(width, "[\d.]+").Value)
        'Dim dblHeight As Double = Double.Parse(System.Text.RegularExpressions.Regex.Match(height, "[\d.]+").Value)

        'If dblHeight > dblWidth Then
        '    opts.Orientation = libWkHtmlToX.Orientation_t.Portrait
        'Else
        '    opts.Orientation = libWkHtmlToX.Orientation_t.Landscape
        '    Dim x As String = width
        '    width = height
        '    height = x
        'End If

        opts.Width = width
        opts.Height = height
        opts.DisableSmartShrinking = True

        ' dpi is not working in wkhtmltopdf version 0.12.4
        ' opts.DPI = 300
        ' zoom setting with value 96/300 = 0.32
        ' opts.ZoomFactor = 96.0 / opts.DPI
        ' opts.ZoomFactor = 1.0 - 96.0 / opts.DPI
        ' opts.ZoomFactor = (1.0 / opts.DPI) / (1.0 / 96.0)
        opts.DPI = 96

        Dim pdfBytes As Byte() = Nothing

        Using p As New libWkHtmlToX.ProcessManager(opts)
            p.Start()
            p.WriteStandardInput(html)
            pdfBytes = p.ReadOutputStream()

            Dim b As Boolean = p.WaitForExit(5000)
        End Using ' p 

        Return pdfBytes

或者,可以将PdfSharp用于.NET-Core
https://github.com/ststeiger/PdfSharpCore

我还将完整的PDF库移植到了NetStandard,可以在这里找到:
https://github.com/ststeiger/PdfSharpNetStandard
(如果不需要Azure托管,建议您选择PdfSharpNetStandard)

就Linux上的ReportViewer-PDF而言:
您首先需要实现很多pinvokes (Linux不实现Windows-API,并且您不能仅将所有dll调用转发给wine)。

到目前为止,我只完成了GetFontData,因为这是最重要的(字体嵌入)。
如果可以给我您的gitlab(而不是中心)帐户名,那么我可以给您对存储库的读取权限。

@ststeiger我知道使用该库部署应用程序是非法的,并且我不打算这样做,但是使用源代码,我至少可以对其进行调试,以了解为什么我无法加载子报表,并且将数据传递给它(我尝试过使用reshaper,但这是一场噩梦)。 如果您想授予我对该存储库的读取权限,我会很喜欢:)我的gitlab用户名是zillemarco(就像github上的一样)

@zillemarco :添加了您。
您应该已经从gitlab得到了一封电子邮件,大概带有回购链接。

尝试使用ILSpy 4.0 Beta 2而不是Resharper:
https://github.com/icsharpcode/ILSpy/releases

如果您需要在.NET Framework中进行调试,请尝试使用Rider进行live-decompile&debug,EAP是免费的:
https://www.jetbrains.com/rider/eap/

@ststeiger收到了电子邮件,谢谢:)也感谢您的提示!

@ststeiger您可以授予对存储库AspNetCore.Reporting的访问权限,以获取okunevpy吗?

@OkunevPY :已添加您。 见邮件。

@ststeiger谢谢。

        string sql = "SELECT * FROM employee";
        // sql = "SELECT * FROM T_Users";

        System.Data.DataTable dt = new System.Data.DataTable();

        using (System.Data.Common.DbDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, csb.ConnectionString))
        {
            da.Fill(dt);
        }

        string fn = "wwwroot/Report1.rdl";
        fn = "wwwroot/InOutTab31.rdlc";

        AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);


        System.Collections.Generic.Dictionary<string, string> parameters =
            new System.Collections.Generic.Dictionary<string, string>();
        parameters["TEN_ID"]="45";
        parameters["START_DATE"]="2018";
        parameters["END_DATE"]= "2018";

        // parameters.Add("in_logo", "base64");

        lr.AddDataSource("DsDayStatusTab31", dt); // DataSet1 is the name of the DataSet in the report




        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 1, null, "");

        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Atom, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Xml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Json, 1, null, "");// KABOOM 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Csv, 1, null, "");

        var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, parameters, "");

        System.Console.WriteLine(rr.TotalPages);


        string dir = @"d:\";
        if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
            dir = "/opt/";

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.css"), rr.SecondaryStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pdf"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xls"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xlsx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.doc"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.docx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.tiff"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.atom.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.json"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.csv"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.rpl"), rr.MainStream); // BOOM 
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pptx"), rr.MainStream);

        BuildWebHost(args).Run();

AspNetCore.Reporting.LocalProcessingException:'在本地报表处理期间发生错误。;没有数据可用于编码1252。有关定义自定义编码的信息,请参阅Encoding.RegisterProvider方法的文档。

@Jhonnybmx :有一个名为google.com的网站,您在其中输入了错误消息,解决方案是第一个链接...

https://stackoverflow.com/questions/49215791/vs-code-c-sharp-system-notsupportedexception-no-data-is-available-for-encodin

System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

嗨,我对.NET Core上的LocalReport感兴趣,可以将rdlc报告导出为PDF。
对我来说,仅Windows版本目前适用。

我遇到了@ amh1979提供的NuGet包AspNetCore.ReportingServices,这正是我所需要的。
问题是此程序包中的InternalLocalReport类是内部的,我需要访问整个API(例如在原始MS LocalReport实现中)。 若要使用SubreportProcessing事件,请调用LoadSubreportDefinition()或GetParameters()方法。

这些方法未在AspNetCore.Reporting.LocalReport类(在AspNetCore.Reporting NuGet中)中实现,因此我需要直接调用它们。

程序集AspNetCore.ReportingServices.dll已为AspNetCore.Reporting.dll程序集设置InternalsVisibleTo。
我可以以某种方式使用https://github.com/amh1979/Reporting/tree/master/AspNetCore.Reporting中带有Reporting.pfx证书的证书(我没有密码)。

你能帮我吗? 有什么解决方案?

@ststeiger您也可以给我访问GitLab存储库AspNetCore.Reporting。 我的GitLab用户名是holajan。
谢谢

此许可下的AspNetCore.ReportingServices
http://go.microsoft.com/fwlink/?LinkId=826162
我已经关闭了

有人可以提供有关如何使用/实现此程序包的文档/线索或提示吗? 非常感谢你。

@ststeiger您能否让我访问AspNetCore.Reporting存储库? 我正在尝试使其在具有PDF的Linux上运行。

@holajan@skivsoft
抱歉,正在度假-到新加坡和泰国旅行很愉快。
授予访问权限后,您应该已经收到一封电子邮件,发送到提供给gitlab的地址。

@azharuddinsayed

当我尝试使用.rdlc文件时,出现异常
'AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.DataRegionExprHost(TMemberType,TCellType).m_memberTreeHostsRemotable'在此上下文中不可访问,因为它是'Friend'。 在localreport.Execute()中
请帮我

我设法重现该错误。
需要进行以下更改:


ReportingServices/AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel/CustomCodeProxyBase.cs

internal AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.IReportObjectModelProxyForCustomCode Report => m_reportObjectModel;
==>
internal protected AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.IReportObjectModelProxyForCustomCode Report => m_reportObjectModel;



internal CustomCodeProxyBase(AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.IReportObjectModelProxyForCustomCode reportObjectModel)
==> 
internal protected CustomCodeProxyBase(AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.IReportObjectModelProxyForCustomCode reportObjectModel)

ReportingServices/AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel/IReportObjectModelProxyForCustomCode.cs
internal interface IReportObjectModelProxyForCustomCode
==> 
public interface IReportObjectModelProxyForCustomCode

除此之外,以下更正
AnyWebReporting \ ReportingServices \ Microsoft.VisualBasic1 \ VBCodeGenerator.cs

System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c " + cmd)
==>
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c \"" + cmd + "\"")

然后,至少在我的情况下,自定义代码有效。
在母版中更新。

@ststeiger感谢您的访问。 您知道如何在Linux上渲染PDF吗? 有太多需要替换的拼字游戏。

@skivsoft :还没有。
您需要用等效的freetype替换所有的pinvokes,这是很多工作。

如果仅需要在Linux上创建PDF,则可以尝试PdfSharpCore或PdfSharpNetStandard:
https://github.com/ststeiger/PdfSharpCore
https://github.com/ststeiger/PdfSharpNetStandard
我在Linux上都使用了它们。
PdfSharpNetStandard更完整,但也使用GDI + / libGDIplus,而PdfSharpCore避开了System.Drawing。

@ststeiger感谢您访问repo。

我可以在.NET Core 2.2 Windows应用程序中使我的报告正常工作(导出为PDF)。
之所以将其复制到您的ReportViewer_NetStandard项目上,是因为我删除了LocalReports,并将InternalLocalReport更改为LocalReport,并公开了类(我需要访问原始的LocalReport API)。

对于我的报告,我解决了两个问题:
一些Visual Basic表达式:
I如果-我添加导入到Microsoft.VisualBasic.Interaction在_ExprHostBuilder_,改为netcoreapp2.2其中_Microsoft.VisualBasic.dll_ Microsoft.VisualBasic.Interaction类是内部和加入我的Microsoft.VisualBasic.InteractionMicrosoft.VisualBasic1。

格式-在_ExprHostBuilder_中将导入添加到Microsoft.VisualBasic.StringsEx ,将类Microsoft.VisualBasic.StringsEx添加到Microsoft.VisualBasic1(因为原始类Microsoft.VisualBasic.Strings是公共的,但是没有Format函数)

System.Environment.NewLine-在_ExprHostCompiler_中添加了对System.Runtime.Extensions.dll的引用。

这是这些代码更改:

In AspNetCore.ReportingServices.RdlExpressions\ExprHostBuilder.cs:
AspNetCore.ReportingServices.RdlExpressions.ExprHostBuilder.GetExprHost(AspNetCore.ReportingServices.ReportIntermediateFormat.ProcessingIntermediateFormatVersion version, bool refusePermissions)
+                codeNamespace.Imports.Add(new System.CodeDom.CodeNamespaceImport("Microsoft.VisualBasic.StringsEx"));
+                codeNamespace.Imports.Add(new System.CodeDom.CodeNamespaceImport("Microsoft.VisualBasic.Interaction"));

In AspNetCore.ReportingServices.ReportProcessing\ExprHostBuilder.cs:
AspNetCore.ReportingServices.ReportProcessing.ExprHostBuilder.GetExprHost(AspNetCore.ReportingServices.ReportProcessing.IntermediateFormatVersion version, bool refusePermissions)
+                codeNamespace.Imports.Add(new System.CodeDom.CodeNamespaceImport("Microsoft.VisualBasic.StringsEx"));
+                codeNamespace.Imports.Add(new System.CodeDom.CodeNamespaceImport("Microsoft.VisualBasic.Interaction"));

In AspNetCore.ReportingServices.RdlExpressions\ExprHostCompiler.cs:
AspNetCore.ReportingServices.RdlExpressions.ExprHostCompiler.InternalCompile(System.AppDomain compilationTempAppDomain, bool refusePermissions)
+                // System.Runtime.Extensions.dll
+                compilerParameters.ReferencedAssemblies.Add(typeof(System.Environment).Assembly.Location);

Added file Microsoft.VisualBasic1\Interaction.cs:
using Microsoft.VisualBasic.CompilerServices;

namespace Microsoft.VisualBasic
{
    /// <summary>The <see langword="Interaction" /> module contains procedures used to interact with objects, applications, and systems. </summary>
    [StandardModule]
    public sealed class Interaction
    {
        public static T IIf<T>(bool condition, T truePart, T falsePart)
        {
            return !condition ? falsePart : truePart;
        }
    }
}






Added file Microsoft.VisualBasic1\StringsEx.cs in (StringsEx.zip)
Added file Microsoft.VisualBasic1\UtilsEx.cs in (StringsEx.zip)
Added file Microsoft.VisualBasic1\Information.cs in (StringsEx.zip)
Added file Microsoft.VisualBasic1\Symbols.cs in (StringsEx.zip)
Added file Microsoft.VisualBasic1\ExceptionUtils.cs in (StringsEx.zip)

StringsEx.zip

使用表达式修复子报表:
我注意到Subreport元素正在使用主报表中的ReportExprHost而不是ReportExprHost用于特定的子报表,因此子报表上的表达式无法正常工作。 我能够在ReportRuntime.LoadExprHostAssembly中找到错误,其中按名称缓存了ExpressionHost.dll程序集,但是所有报表和子报表的名称始终是相同的“ _ExpressionHost_”。 我删除了此缓存。
代码更改:

In AspNetCore.ReportingServices.RdlExpressions\ReportRuntime.cs:
-                private static readonly System.Collections.Hashtable ExpressionHosts = new System.Collections.Hashtable();

AspNetCore.ReportingServices.RdlExpressions.ReportRuntime.LoadExprHostIntoCurrentAppDomain(byte[] exprHostBytes, string exprHostAssemblyName, System.Security.Policy.Evidence evidence, bool includeParameters, bool parametersOnly, AspNetCore.ReportingServices.ReportProcessing.OnDemandReportObjectModel.OnDemandObjectModel objectModel, System.Collections.Generic.List<string> codeModules)
-                System.Reflection.Assembly assembly = LoadExprHostAssembly(exprHostBytes, exprHostAssemblyName, evidence);
+                System.Reflection.Assembly assembly = LoadExprHostAssembly(exprHostBytes);

            private static System.Reflection.Assembly LoadExprHostAssembly(byte[] exprHostBytes)
            {
                try
                {
                    new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.ControlEvidence).Assert();
                    return System.Reflection.Assembly.Load(exprHostBytes);
                }
                finally
                {
                    System.Security.CodeAccessPermission.RevertAssert();
                }
            }

请查看这些更改,如果您认为有必要,也可以在回购中进行这些更改。

谢谢。

@holajan :如果我将System.String添加到名称空间,
Ambigous call to Replace - cannot resolve call
如果我添加Microsoft.VisualBasic.Interaction类,则会得到:
ambigous call to Microsoft.VisualBasic.Interaction
当我在NetCore或.NET Framework 4中运行它时。
也许这仅适用于.NET Core 2.2。

如果缓存不正确,则最好不要缓存。
同意该更改。
我将旧代码放到#ifdef false (而不是删除它)。

@ststeiger我编辑了我的注释,用于System.String是错误的,我现在实现了Microsoft.VisualBasic.StringsEx来代替Format和其他功能。 抱歉

是的, Microsoft.VisualBasic.Interaction仅在.NET Core 2.2中工作,因为类Microsoft.VisualBasic.Interaction在.NETCoreApp v2.2内部的Microsoft.VisualBasic.dll中,而在.NETCoreApp v2.09的Microsoft.VisualBasic.dll中
我不知道如何更好地解决此问题,但是使用.NET core 3.0可能仍会进行更改。

@holajan :这么久,让我们等到3.0
我公开了InternalLocalReport。
现在关于它的公开性的名字很奇怪;

@holajan :添加了Microsoft.VisualBasic.StringsEx,现在可以使用
不得不为.NET 4添加IReadOnlyDictionary,但这只是次要说明。
你能测试一下是否适合你。

@ststeiger我测试了它。
我必须#如果假更改为Microsoft.VisualBasic1._Interaction.cs表达I如果工作到#如果真
否则,它将正常工作。
谢谢

@holajan :好的,应该是这样。 解决方案中的定义可能会更好。

该线程中的每个人都应对此添加投票,网址为//feedback.azure.com/forums/908035-sql-server/suggestions/33241936-develop-a-ssrs-reportviewer-for-asp-net-核心

截至2019/03年,它是最受欢迎的功能中的第7位: https ://feedback.azure.com/forums/908035-sql-server?category_id=325159

编辑:截至2019/05,其排名第五

编辑:截至2019/07,其排名第四

        string sql = "SELECT * FROM employee";
        // sql = "SELECT * FROM T_Users";

        System.Data.DataTable dt = new System.Data.DataTable();

        using (System.Data.Common.DbDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(sql, csb.ConnectionString))
        {
            da.Fill(dt);
        }

        string fn = "wwwroot/Report1.rdl";
        fn = "wwwroot/InOutTab31.rdlc";

        AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);


        System.Collections.Generic.Dictionary<string, string> parameters =
            new System.Collections.Generic.Dictionary<string, string>();
        parameters["TEN_ID"]="45";
        parameters["START_DATE"]="2018";
        parameters["END_DATE"]= "2018";

        // parameters.Add("in_logo", "base64");

        lr.AddDataSource("DsDayStatusTab31", dt); // DataSet1 is the name of the DataSet in the report




        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 1, null, "");

        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Rpl, 1, null, ""); // Kaboom 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Html, 2, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.ExcelOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Word, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.WordOpenXml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Atom, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Xml, 1, null, "");
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Json, 1, null, "");// KABOOM 
        // var rr = lr.Execute(AspNetCore.Reporting.RenderType.Csv, 1, null, "");

        var rr = lr.Execute(AspNetCore.Reporting.RenderType.Excel, 1, parameters, "");

        System.Console.WriteLine(rr.TotalPages);


        string dir = @"d:\";
        if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
            dir = "/opt/";

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.css"), rr.SecondaryStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pdf"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xls"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xlsx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.doc"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.docx"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.tiff"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.atom.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.xml"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.json"), rr.MainStream);
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.csv"), rr.MainStream);

        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.rpl"), rr.MainStream); // BOOM 
        // System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.htm"), rr.MainStream);
        System.IO.File.WriteAllBytes(System.IO.Path.Combine(dir, "foo.pptx"), rr.MainStream);

        BuildWebHost(args).Run();

AspNetCore.Reporting.LocalProcessingException:'在本地报表处理期间发生错误。;没有数据可用于编码1252。有关定义自定义编码的信息,请参阅Encoding.RegisterProvider方法的文档。

添加以下代码:
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
它解决了我的问题

你好

我尝试使用以下代码在HTML中导出报告,但显示不正确。

.rdl文件包含图表

我已附上HTML的屏幕截图

非常感谢您能为我们解决此问题提供帮助。

谢谢

平台:ASP.NET Core

公共字符串_reportPath = @“ .. \ RenderReportAPI \ employeeChart.rdl”;

字符串mimtype =“”;
int扩展= 1;

       LocalReport localReport = new LocalReport(_reportPath);

    _dataSourceName = "DataSet1";
    _dataSourceList = Employee.GetEmployees();                                   
    localReport.AddDataSource(_dataSourceName, _dataSourceList);



    System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
    var result = localReport.Execute(RenderType.Html, extension, null, findString: mimtype);

Chart_html

@chinturathod :“报告图表”元素的URL显示什么?
html-renderer具有CSS的辅助输出流。
它是否包含base64编码的图像? 还是仅仅是图像处理程序的链接?

@ststeiger
嗨,请在下面找到HTML和CSS
HTML:

\"Report
19-03-2019 12:08:25







CSS:

“ #rsoReportDiv .A97993c8d452f40d4910a317776d607f616xBc {
边框:1pt无黑色;
背景颜色:透明;
}

rsoReportDiv .A97993c8d452f40d4910a317776d607f616xB {

border:1pt none Black;
background-color:Transparent;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f69 {

word-wrap:break-word;
word-break:break-word;
white-space:pre-wrap;
min-width:139.70mm;
overflow:hidden;
width:139.70mm;
border:1pt none Black;
background-color:Transparent;
font-style:normal;
font-family:'Segoe UI Light';
font-size:28pt;
font-weight:400;
text-decoration:none;
unicode-bidi:normal;
color:Black;
vertical-align:top;
text-align:left;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f614 {

border:1pt none #d3d3d3;
background-color:White;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f65c {

border:1pt none Black;
background-color:Transparent;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f65 {

min-width:152.40mm;
min-height:65.14mm;
width:152.40mm;
border:1pt none Black;
background-color:Transparent;

}

rsoReportDiv .A97993c8d452f40d4910a317776d607f63 {

word-wrap:break-word;
word-break:break-word;
white-space:pre-wrap;
padding-left:2pt;
padding-top:2pt;
padding-right:2pt;
padding-bottom:2pt;
border:1pt none Black;
background-color:Transparent;
font-style:normal;
font-family:'Segoe UI';
font-size:10pt;
font-weight:400;
text-decoration:none;
unicode-bidi:normal;
color:Black;
vertical-align:top;
text-align:right;

}

rsoReportDiv .rsr1 {

height:100%;
width:100%

}

rsoReportDiv .rsr2 {

height:100%;
width:100%;
overflow:hidden

}

rsoReportDiv .rsr3 {

height:100%

}

rsoReportDiv .rsr4 {

border-style:none

}

rsoReportDiv .rsr5 {

border-left-style:none

}

rsoReportDiv .rsr6 {

border-right-style:none

}

rsoReportDiv .rsr7 {

border-top-style:none

}

rsoReportDiv .rsr8 {

border-bottom-style:none

}

rsoReportDiv .rsr10 {

border-collapse:collapse

}

rsoReportDiv .rsr9 {

border-collapse:collapse;
table-layout:fixed

}

rsoReportDiv .rsr11 {

width:100%;
overflow-x:hidden

}

rsoReportDiv .rsr12 {

position:absolute;
display:none;
background-color:white;
border:1px solid black;

}

rsoReportDiv .rsr13 {

text-decoration:none;
color:black;
cursor:pointer;

}

rsoReportDiv .rsr14 {

font-size:0pt

}

rsoReportDiv .rsr15 {

direction:RTL;
unicode-bidi:embed

}

rsoReportDiv .rsr16 {

margin-top:0pt;
margin-bottom:0pt

}

rsoReportDiv .rsr17 {

height:100%;
width:100%;
display:inline-table

}

rsoReportDiv .rsr18 {

height:100%;
display:inline-table

}

rsoReportDiv * {

 box-sizing: border-box;

}

报告图表元素
Report chart
我认为这个错误导致了问题

谢谢..

@ststeiger

嗨,有更新吗?

@chinturathod
我目前正在使用CEF-pdf作为wkhtml2X的替代品,并正在使用SwissRe Reports。

我最早有两周的时间有时间研究这个项目。

是否有可以授予我访问权限的AspNetCore.ReportingServices程序包的存储库(专用或其他)?

@clintb :我需要您的git LAB帐户名,所以我可以授予您访问权限。
然后,您会收到一封电子邮件,其中包含回购访问权限的git lab帐户的电子邮件地址。

嗨Stefan,我的gitLab是c_l_i_n_t。 谢谢!

2019年4月26日星期五,12:18 PM Stefan Steiger [email protected]
写道:

@clintb https://github.com/clintb :我需要您的git LAB帐户名,所以
我可以授予您访问权限。
然后,您将收到一封电子邮件,发送到git lab的电子邮件地址
包含回购访问权限的帐户。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/aspnet/AspNetCore/issues/1528#issuecomment-487133308
或使线程静音
https://github.com/notifications/unsubscribe-auth/ABURO5ILQUEGMZARNW2HNALPSM2M5ANCNFSM4CFRN7MQ

@clintb :您已添加。

@ststeiger ,您好,如果愿意,请授予lotatrees的回购权限。 感谢您的工作和帮助。

@lotsatrees :您已添加。

感谢Stefan,很高兴随时为您购买优质的啤酒。

@ststeiger ,您好,我的gitlab是edgardoreyes。 非常感谢。

@ststeiger
我的gitlab是ikourfaln
谢谢

@ikourfaln@edgardoreyes :增加了两个; 您应该已经收到一封电子邮件,通知您在gitlab中注册的邮件帐户。

@ststeiger ,是否也可以添加自己(gitlab上的Mhirji)?

谢谢!!

@Mhirji :完成。

谢谢!!!

为什么不仅仅创建一个Report Server Project并将其用作任何项目类型的服务?
您的ASP.NET Core项目将只需要报表服务的URL即可显示报表。
这种方法有问题吗?

@ststeiger我也可以访问吗? (gitlab上的ConstantDisaster)预先感谢

@ConstantDisaster :已添加。
@mshwf :不,实际上这正是我想要做的-因此我们可以在自己的应用程序中运行报告,而无需Reportserver(始终是Windows身份验证的问题-由于某些原因,IT部门无法将新用户添加到组中-再加上卸载的Service Pack始终存在问题,由于客户想要跳过版本,不愿更新到最新的SQL Server版本,ReportViewer和ReportServer之间呈现不一致,我们自己的sysadmin太懒而无法安装任何东西,等等)。 一如既往只是缺乏时间。 另外,这是西北欧地区夏天的头一个晴天,我不想错过他们。

@ststeiger还有更好的选择吗? (我尝试阅读此线程,但时间很长!)
还可以授予我访问GitLab存储库(mshwf)的权限吗?
谢谢

请支持此请求,希望Microsoft听我们的意见!

@ststeiger您也可以加我吗?
我的gitlab用户名是k3flo
非常感谢
Vielen Dank😊

@ststeiger感谢您的添加,那么如何再次开始使用它呢? 在asp net核心项目中? 以为它有自述之类的东西,再次感谢。

@ConstantDisaster :在AnyWebReporting\Any_TestCode\TestReport.cs有一个“示例”。
它显示了如何将带有参数和数据集的报告呈现为PDF。

简而言之:
1)为报告参数创建字典:

System.Collections.Generic.Dictionary<string, string> parameters =
                new System.Collections.Generic.Dictionary<string, string>();

2)将报表中的所有参数添加到字典中,例如

parameters.Add("in_language", "DE");
parameters.Add("in_something_uid", "9A892D4B-B4E3-4804-AAB6-97EAB37B7849");

3)创建一个新的基于LocalReport并加载报告

string fn = "/full/path/to/SomeReport.rdl";
AspNetCore.Reporting.LocalReport lr = new AspNetCore.Reporting.LocalReport(fn);

然后,对于仅在参数中使用的所有数据集,您可以添加一个空的数据表(非NULL)
lr.AddDataSource("SEL_Standort", new System.Data.DataTable());

对于每个使用的数据集,您需要使用该数据集的查询结果填充数据表,并将该数据集添加到数据源:

lr.AddDataSource("DATA_Schluesselbestandeskontrolle", dt);

然后,您可以执行报告,获取结果并将其写入某个位置,例如驱动器d:

var rr = lr.Execute(AspNetCore.Reporting.RenderType.Pdf, 1, parameters, "");
System.IO.File.WriteAllBytes(System.IO.Path.Combine(@"d:\", "Bestandeskontrolle.pdf"), rr.MainStream);

我添加了一个示例HTML页面,该页面模仿了草稿版本中的ReportViewer 2014&2017报告界面的设计。 如果您再次从git获取,则会在以下位置找到它:

AnyWebReporting\AnyWebReporting\wwwroot
AnyWebReporting/AnyWebReporting/wwwroot/index.htm
AnyWebReporting/AnyWebReporting/wwwroot/index2014.htm
AnyWebReporting/AnyWebReporting/wwwroot/logon.htm

就是这样。
如果需要在Web上显示报告,则可以通过将相应的Enum传递给lr.Execute(RenderType.HTML5_0或HTML4_0或Mhtml)并传递正确的页码来呈现为html。 结果(HTML)在MainStream中,而CSS在SecondaryStream中。

但是,通过JavaScript将ReportViewer的index.htm与lr.Execute连接起来,目前您需要自己做。 暂时还没有做到这一点。 现在,我需要它来生成要附加到电子邮件的PDF。

@ k3flo @mshwf :已添加。

@mshwf

@ststeiger还有更好的选择吗? (我尝试阅读此线程,但时间很长!)

据我所知,否则我会使用它。
在.NET Core 3.1发行版(LTS)之后,也许我们会在这方面看到一些东西,因为那样便可以自由地创建基于.NET Core的仅Windows的ReportViewer。

但是,这样的事情与该项目一样容易,所以也许他们会花一些时间删除所有System.Drawing(以及对GDI +的WinAPI调用)代码,并正确地进行操作,也就是说跨平台。 虽然我认为这不太可能。 没有不高兴,但(咳嗽)是正感到惊讶。

问题是报表可以包含VB代码,并且.NET Core(<3)中的VB支持目前是有问题的-充其量是最多的。 .NET Core 3将纠正(理论上应该是),并且,如果他们制作了ReportViewer,则他们很可能至少要等到LTS发布。

@mshwf
您无需阅读整个线程。
您需要做的就是git-clone该项目并查看示例报告(尽管您没有数据库来运行它)。

您能在gitlab上加我吗?
直流

@dcga :已添加。

嗨,您能加我到gitlab吗? 我现在将报表转换为ASP.net Core项目。

@ ericyu67 :我想你的gitlab帐户名是ericyu吗? 在这种情况下,您被添加。

没错,谢谢。

@ststeiger ,你能加我吗?
罗德里格

@rodrigorrl :已添加。

@ststeiger ,你能加我吗?

@myersBR :完成。

@ststeiger可以加我吗?

@acofalc :添加@ aco.mit

嗨, @ststeiger,请加我:oblin228,谢谢。

有什么消息吗? 我正在使用ASP.NET Core,但我拒绝回到Webforms。 我有一个报告项目,我将URL从报告服务器馈送到我的应用程序以下载文件。 问题是它不断要求进行Windows身份验证,我想避免这种情况...

@oblin :已添加。

@jfcaldeira :只要您在Windows上运行该应用程序,gitlab上的reportviewer就会或多或少地起作用(到目前为止,HTML输出中的图像存在打开问题)。 在Linux上运行它,只要您不使用PDF,TIFF或PowerPoint作为输出格式(不知道单词),它就应该可以工作,但是Excel,html,xml和json在Linux上也可以工作(在我的1份报告测试-无法说出使用完整功能集是否没有爆炸)。

但是,如果您的问题是在SSRS上进行Windows身份验证,那么为什么不使用自定义安全性(也就是SSRS表单身份验证)。

为此,请参见此处:
https://www.codeproject.com/Articles/675943/SSRS-2012-Forms-Authentication
https://github.com/ststeiger/SSRS-Localizer
https://github.com/ststeiger/CustomHttpHeaders
https://github.com/microsoft/Reporting-Services/tree/master/CustomSecuritySample

您可能需要使用JavaScript中的Form-Post登录用户,并设置P3P策略(通过HTTP模块通过SSRS在SSRS中),以使SSRS-auth-cookie可以在IE跨域中持久存在...(注意:如果您使用虚拟目录,并且在一个SSRS上有2个应用程序,则application1 [在SSRS域上]的auth-cookie将覆盖也在SSRS域上的application2的auth-cookie。

@oblin :已添加。

@jfcaldeira :只要您在Windows上运行该应用程序,gitlab上的reportviewer就会或多或少地起作用(到目前为止,HTML输出中的图像存在打开问题)。 在Linux上运行它,只要您不使用PDF,TIFF或PowerPoint作为输出格式(不知道单词),它就应该可以工作,但是Excel,html,xml和json在Linux上也可以工作(在我的1份报告测试-无法说出使用完整功能集是否没有爆炸)。

但是,如果您的问题是在SSRS上进行Windows身份验证,那么为什么不使用自定义安全性(也就是SSRS表单身份验证)。

为此,请参见此处:
https://www.codeproject.com/Articles/675943/SSRS-2012-Forms-Authentication
https://github.com/ststeiger/SSRS-Localizer
https://github.com/ststeiger/CustomHttpHeaders
https://github.com/microsoft/Reporting-Services/tree/master/CustomSecuritySample

您可能需要使用JavaScript中的Form-Post登录用户,并设置P3P策略(通过HTTP模块通过SSRS在SSRS中),以使SSRS-auth-cookie可以在IE跨域中持久存在...(注意:如果您使用虚拟目录,并且在一个SSRS上有2个应用程序,则application1 [在SSRS域上]的auth-cookie将覆盖也在SSRS域上的application2的auth-cookie。

您好,谢谢您答复我的问题。 我还没听说过gitlab上的这个reportviewer,您能告诉我它的锚点吗?

关于Windows身份验证,问题在于我让用户在ASP.NET Core中的应用程序上使用Cookie身份验证对用户进行了身份验证,而让用户访问报告的解决方法基本上是将带有参数的直接URL传递给锚点的href并选择PDF作为格式。 我试图找到一种不对用户进行身份验证的方法,因为这使最终用户必须进行两次身份验证很烦人。 我已经在使用一个特定的帐户来访问数据源了,这真是令人沮丧。

嗨, @ ststeiger-我的gitlab是arunputhran。 可以给我访问权限吗? 非常感谢!

重新发布此消息是因为它已被所有“允许我访问gitlab”请求掩埋。

遇到此线程的每个人都应投票赞成要添加的.NET Core SSRS,在这里: https :

从顶部第7位开始,到现在最受欢迎的SQL Server功能从顶部第4位上升(https://feedback.azure.com/forums/908035-sql-server?category_id=325159)

编辑:因为这个帖子,它现在排名第三

不确定是否有帮助...

@arunputhrankyc :已添加。

@ k290 :不,正如您所看到的,SQL Server Management Studio 2017的深色主题显然更重要::scream::man_facepalming::woman_facepalming:
显然,他们还没有听说过SQL-ops-studio / AzureDataStudio

我认为,本着这种精神,有人应该在笑话清单中添加平面设计。
不幸的是,还不是4月1日:wink:

顺便说一下,我从Web api获取报告为pdf,并且我不使用任何wcf位。
只是soap / asmx调用和http调用。
在这样做的时候,我通过了credentails,没有任何问题。
我的代码是asp.net 4.6 / web api 2
如果您想看看我在做什么,我下周可以在github上放一些代码供您查看。
我将报表服务器称为2016,但我所做的大部分工作都将与较旧的ssrs版本一起使用。

您好,我读了您对您如何处理SSRS的评论。 我也在做类似的事情,我在ASP.NET Core应用程序中拥有一个锚点,该应用程序具有直接指向包含参数和格式扩展名的报表的URL。 但是,问题在于它要求进行Windows身份验证。 由于用户已经使用Cookie身份验证登录了我的应用程序,有没有办法停止询问? 只要下载报告,我什至都不在乎显示报告,但是跳过身份验证会很好

@arunputhrankyc :已添加。

@ k290 :不,正如您所看到的,SQL Server Management Studio 2017的深色主题显然更重要k🤦♂♂♀
显然,他们还没有听说过SQL-ops-studio / AzureDataStudio

我认为,本着这种精神,有人应该在笑话清单中添加平面设计。
不幸的是,还不是4月1日。

好吧,我肯定会为SSMS的一个黑暗主题而杀,但是我会为该SSRS徒劳。 直接从SQL呈现分组数据可以节省大量工作。

很好的解决方案,请在gitlab中添加我: @kholossok ,谢谢

也请在gitlab中添加我:@EMaderbacher

@kholossok@EMaderbacher :已添加。

也请加我@jfcaldeira

@jfcaldeira :您需要给我一个git lab帐户。
这是一个git hub帐户。
免费。 https://gitlab.com
私有存储库当时不是在github上免费的。

@ststeiger
私有存储库现在在GitHub上是免费的,限制是协作者的数量。

@jfcaldeira :您需要给我一个git lab帐户。
这是一个git hub帐户。
免费。 https://gitlab.com
私有存储库当时不是在github上免费的。

我已经使用相同的用户名创建了一个帐户

@jfcaldeira :已添加。 您应该已经收到一封包含访问信息的电子邮件。
@ikourfaln :我知道。 但是,不知道github私有存储库中的3个协作者没有限制。 很高兴知道,谢谢

Gitlab的局限性:

为了庆祝今天的好消息,我们将GitLab.com上每个存储库的存储限制从5GB永久提高到10GB。 和以前一样,GitLab.com上的公共和私有存储库是不受限制的,没有转移限制,并且包括无限的合作者。

我也可以加吗? 我的GitLab帐户是barryjsilver。 谢谢!

可以加我吗? @jyanosu谢谢!

@BarryJSilver :已添加。

@jyanosu :我需要git lab .com帐户,而不是github。

@ststeiger糟糕,只需进行设置即可。.相同的用户名@jyanosu

@jyanosu :已添加。

@ststeiger可以添加我的gitlab帐户@ kanichi123
谢谢!

@ kanichi123 :已添加。

@ststeiger也

@sheryever :已添加。

@ststeiger,请您添加我的gitlab帐户@PentaTech
谢谢!

@ststeiger也可以加我吗? @glebteterin
谢谢!

@ PentaTech ,@ g-rad:已添加。

@ststeiger对此很努力,能否请您添加gitlab帐户brad0000?

@ brad0000 :完成。

@ststeiger ,您也可以加我吗? gitlab帐户:wyepez。 谢谢

@wyepez :已添加。

@ststeiger也可以加我吗?

Gitlab用户名:choudeshell

@choudeshell :已添加。

你能加我吗? 谢谢!

您的解决方案是否可以与.rdlc(以及服务器端.rld)一起使用? 谢谢

您的解决方案是否可以与.rdlc(以及服务器端.rld)一起使用? 谢谢

@mpirritano :是的,事实上,RDL和RDLC之间没有太大区别。
但这只是网络。 没有Windows窗体。
我需要一个git lab帐户来添加您,而不是github。

@ststeiger谢谢-我现在已经创建了一个GitLab帐户:@mdpirrit

太好了-我只需要针对.NET Core的ASP .NET Core。 谢谢!

@mpirritano :添加了,您应该已经将电子邮件发送到用于注册gitlab的电子邮件帐户。

得到它了; 谢谢!

@ststeiger效果很好,但无法渲染图表。 -它呈现错误的图表区域:“无法加载文件或程序集“ System.Windows.Forms,版本= 4.0.0.0”

这是已知的限制,还是我缺少什么?

谢谢

@ststeiger此外,它似乎并不像子报表受支持。 即似乎没有子报表处理事件处理程序可将数据源​​添加到子报表实例

谢谢

你能加我吗? 谢谢! @shabyralieva

您的解决方案是否可以与.rdlc(以及服务器端.rld)一起使用? 谢谢

@mpirritano :是的,RDL和RDLC之间确实没有太大区别。
但这只是一个网络。 没有Windows窗体。
我需要一个Git Lab帐户来添加您,而不是GitHub。

你能加我吗? 谢谢! @shabyralieva

@azikaa :完成。 Добавлено;)

@mpirritano

这是已知的限制,还是我缺少什么?

是的,我知道它可能存在的局限性。
而且,它还存在HTML输出图像的问题。
开放点。
我什至没有想到子报表。
可悲的是,我们也有一些,所以这也是我的问题。
说到它,我什至不知道在整个框架的普通ReportViewer中如何处理子报表,特别是因为它们可以递归。

它可能在某个地方有问题,因为.NET Core中该版本中不存在“ System.Windows.Forms,Version = 4.0.0.0”,并且该程序集在ReportViewer中也称为System.NetStandard.Forms, .NET Core。 可能在完整框架上工作,因为确实存在System.Windows.Forms,版本= 4.0.0.0。

System.Windows.Forms的问题可能很容易解决,就像将程序集名称和版本(无论源代码中隐藏在何处)放入ifdef中一样,子报表不是我想的。

我仍然必须在本周完成报表发送服务,因此我可能可以在下周的某个时间查看System.Windows.Forms问题。

就子报表而言:无论如何这都是一个坏主意,倾向于在PDF和Excel中造成问题,并且如果您只有1个报表,我建议您看看是否有可能以某种方式完全消除子报表,并使所有内容都包含在一份报告中。

Добавлено
如何获取数据库COR_Basic_SwissLife_UAT?

:rofl:哈哈,好人,你不知道,数据库是机密的。
但是您可以使用自己的数据库来制作自己的示例报告。
您应该从示例中看到如何使用它。

@ststeiger谢谢。 实际上,我看到在AsNetCore.Reporting.InternalLocalReport中定义了SubreportProcessing事件。 我可以尝试为此创建一个公共接口,看看是否可以将数据源传递给子报表实例。 我可能也要等到下周才能解决这个问题...

我也尝试避免使用子报表,但是我发现如果需要在重复部分中使用重复部分,则需要使用子报告。 关于Excel,可以使用rdlc / rdl在Excel中将每个子报表实例呈现为工作表。

重新发布给新手。

该线程中的每个人都应对此添加投票,网址为//feedback.azure.com/forums/908035-sql-server/suggestions/33241936-develop-a-ssrs-reportviewer-for-asp-net-核心

今年三月,它排在第七位。

现在,我们从SQL Server建议的顶部开始将其排在第二位: https :

我们可以击败黑暗模式吗?

@ststeiger我今天实际上有一点时间,并且能够使用.docx,.xlsx和.pdf中的子报表成功呈现报告。

作为对本地副本的快速测试-我将“ LocalReport”类的“ localReport”属性的访问修饰符从“内部”更改为“公共”。 然后,我可以像往常一样为“ SubreportProcessing”事件编写一个处理程序(在该程序中,我会将参数的值读取到子报表实例中,并使用它来过滤要传递到子报表实例数据源中的数据集)

我不知道如何使用.NET Core解决图表渲染问题。 因此,如果您能够找到一个很棒的解决方案。 但是除此之外,我认为您的解决方案可以完成我需要做的所有事情(我个人从来没有以HTML格式呈现报告)

谢谢

出口-单词,excel不正常吗?
FormatException:标头在索引0处包含无效值:“'

服务非常慢。 该怎么办? 请帮忙....

大家好,我刚刚使用内置在SSRS中的ReportExecutionService.asmx编写了报表查看器控件的自定义端口,并且我的目标是ASP.NET MVC。 我有人建议将其移植到.NetCore和MVC,所以我已经完成了。 试试看,让我知道你们的想法: https :

艾伦

出口-单词,excel不正常吗?
FormatException:标头在索引0处包含无效值:''

服务非常慢。 该怎么办? 请帮忙....

@azikaa :您使用的是MvcReportViewer还是AspNetCore.ReportViewer?

我们正在解决此问题,因为它与此回购协议没有直接关系,并且基于此处的评论,SSRS团队已经了解到了此反馈。 考虑到评论的数量,现在已经无法管理。

@ k290的回复是在这里最可行的回复,因此请在这里遵循他的建议:

重新发布给新手。

该线程中的每个人都应对此添加投票,网址为//feedback.azure.com/forums/908035-sql-server/suggestions/33241936-develop-a-ssrs-reportviewer-for-asp-net-核心

今年三月,它排在第七位。

现在,我们从SQL Server建议的顶部开始将其排在第二位: https :

我们可以击败黑暗模式吗?

此页面是否有帮助?
0 / 5 - 0 等级