好的,那么在网络上显示CR报告中的图像的眼泪轨迹如下:
1) 假设如下:
a) CR 2008 又名 CR 12。我不知道早期版本,但 XIR2 (11.5) 可能有效。
b) 需要在报告中以 Web 显示图片,并带有本地工作站开发和预览
c) IIS、ASP.NET 应用程序、.NET 4.0
d) Crystal Reports 安装正确(这是一个完全不同的讨论,但我只想说,您最好有一个名为 aspnet_client 的文件夹,其子目录如下:
**system_web
4_0_30319
crystalreportviewers12**
等等
这与 Web 应用程序的位置平行。 还有更多 - 但这里没有......
e) 图像类似于照片或其他任何东西,但大小合理且字节数不会太大。
f) 每个图像都存在缩略图,或者默认的缩略图文件可用。
g) 它们是 JPG、PNG 或 BMP 图像。否则,您将不走运 AFAICT。如果它们是您希望在同一列表中显示的 Word、PDF 等文档,您也需要为这些文档提供缩略图。但是,让我们继续关注图像主题...
h) 您将图像组织到您的网络服务器上的文件夹层次结构中,或者您的网络服务器可以访问,但无论如何,网站都可以访问。假设它们都在一个主要位置 D:\MyDocuments
我没有尝试过像原始问题那样引用 FTP 站点,但我怀疑它会起作用。
2) 您需要一个数据库表或其他类型的网络服务器可访问的存储库来注册您的图像。 DB 格式是灵活的,但我们假设它是一个与您感兴趣的主要领域相关的列表,其中每个主要项目都有 0:N 图像,例如住宅图片、桥梁图片或家庭检查。此表包含文件的完整路径、相对路径或文件夹位置以及专用文件名列。无论如何,但他们必须创建一个文件路径,例如:
D:\MyDocuments\folderA\folder1\area51\whatever\myfile.png
所以数据库保存整个事物,或它的一部分,或位,或其他任何东西。
3) 在本地/独立/不使用浏览器查看报告时,根文件夹是 D:\MyDocuments。这是一个任意名称,但现在请注意它。
4) 您注册该根文件夹,以便 CR 可以找到它。这可以硬连线到您的报告中(坏)或从 INI 文件(嗯,好的)或数据库字段中查找(为什么不,因为您正在注册图像?)或作为参数传递给您的想要显示图片或文档链接的报告(很简单,但是当您部署到其他文件系统时会发生什么?)
5) 在您显示图片的报告中,我假设这里有 N / 个感兴趣的项目,如上面 (2) 中所述,您插入了 CR 设计师的图片。将其链接到一些真正伪造的图片或默认图像,以便您可以判断您是否正在解析文件名......
6) 图片thumbnail's 路径从数据库中检索并在必要时用反斜杠组合成一个文件名。它将存储在报告中的 Shared StringVar FullQualifiedThumbnailFileName (比方说)中,并包含您在步骤 (4) 中为报告提供的文档根目录,并存储在专用的 Shared StringVar DocRoot 中(比方说)加上计算的文件名。所以公式字段 FullyQualifiedThumbnailFileName 看起来像:
{@DocRoot} & FolderLocationFromDB & ThumbnailFileNameFromDB 或在现实生活中:
D:\MyDocuments\folderA\folder1\area51\whatever\tn_myfile.png
7) 现在你有了一个缩略图文件名。将它放在您的草稿报告中的任何位置,这样您就可以在设计期间看到它正在解决的问题。执行完全相同的操作来引用 REAL 文件名并创建一个名为 FullyQualifiedThumbnailFileName 的变量。如果构造正确,它应该可以用图片查看器打开。也可以将它放在某个地方,以便您阅读并使用它进行测试。
8) 右键单击报表上的图片对象,选择格式图形,单击图片选项卡,然后打开图片位置的公式图标。
在你开始抱怨我之前,请先看看上面的假设——我不知道哪个早期版本的 CR 支持这一点,或者他们是否以不同的方式做。
然后,在公式编辑器中,输入以下内容:
{@FullQualifiedThumbnailFileName} 您刚刚创建的。您的缩略图是网络服务器或开发工作站上本地文件名的 Windows DOS 路径。
9) 现在向您的报告添加一个参数,或创建一个公式变量,或其他任何默认包含字符串“file://”的变量。这将在运行时用 httpContext.Current.Session 应用程序根目录替换,但我们将在一分钟内完成。我猜你本可以早点这样做的......命名为 WebURLRoot
10) 创建一个名为 txtImageURL 的公式字段无论如何,名称由您决定,但猜猜这里是什么?类似于以下内容:
if lowercase( {@WebURLRoot} ) = "file://" THEN
{@WebURLRoot} &
REPLACE( {@txtDocumentFileFullyQualifiedName},"/","\")
else
URLENCODE( {@WebURLRoot} &
REPLACE(
{*DocumentFileNameFromYourSource*}
,"\","/") )
将文件名 DocumentFileNameFromYourSource 附加到 WebURLRoot 对我有用,因为在我的情况下,我的相对路径不包括 DocRoot。你的情况可能不同。无论如何,在独立模式中,该变量应该解析为:
file://D:\MyDocuments\folderA\folder1\area51\whatever\myfile.png
这不是缩略图。在网络上运行时,它应该解析为:
http://somewebhost/website/folderA/folder1/area51/whatever/myfile.png
因为我们要以某种方式将 http://localhost/website 提供给变量 WebURLRoot。我使用从 Web 应用程序传递的参数来做到这一点。它可以被查找或硬连线,但请记住,如果网站被重新定位会发生什么?
将 {@txtImageURL} 放入超链接计算文件名公式中,然后单击选项以表明它来自 Internet 上的网站,也就是您的本地开发服务器或其他任何地方。
在独立模式下,txtImageURL 中的文件字符串带有反斜杠。在运行时,它们被设置为完整文件名的正斜杠。 Crystal 的 URLEncode 函数使它们非常适合网络用途。
再次将 txtImageURL 拖放到您的开发表面上,直到它变直为止。
11) 您现在拥有一个 CR RPT,其中包含
a) 保存文档树 C:\MyDocuments 的 Windows 根目录的变量,您通过任何方式将其提供给报告。我将它存储在我的应用程序连接到的数据库中。
b) 保存缩略图的窗口路径的变量,由数据库中的缩略图名称加上文档根目录构成
c) 保存真实文件名的 Windows 路径的变量,同样由数据库中的实际文件名加上文档根目录构成
d) 一个网站 URL 词干,它是网站的file:// 在开发期间 和 http://localhost/website/ 在运行时。你通过了这个
e) 将网站 URL 主干与实际文件相结合的图像文件的工作 URL。
到目前为止还好吗?来一杯啤酒。也许 2。
C# 变化
1) 好的,所以我们需要调整我们的世界以在运行时将网站 URL 词干作为参数传递给报告。您无法使用 Crystal Reports 查看器在 Web 上执行此操作。假设您已经遵循了有关如何从 Web 应用程序加载、参数化和显示报告的众多示例之一,并且我认为您可以通过 Google 找到这些示例,请确保您在应用程序的某个地方执行此操作。我在 Session_Start 事件中的 Global.asax.cs 中找到了我的,根据作者的说法,这似乎非常合理... 请注意,功劳归功于引用的 URL 人物...:
// so Crystal can receive the APP_Path as an argument
// Code that runs when a new session is started
// http://aquesthosting.headtreez.com/doc/d9ccf4d8-1873-469e-9dca-815e5854b963
string appPath = System.Web.HttpContext.Current.Request.ApplicationPath.ToLower();
if (appPath == "/") //a site
appPath = "/";
else if (!appPath.EndsWith(@"/")) //a virtual directory i.e. in a subfolder
appPath += @"/";
Session["APP_Path"] = appPath; //stores the value to a session variable for us to use
2) 现在,在您为报告创建参数的地方,确保将 Session["APP_Path"] 作为参数传递,如下所示:
// START CHANGE
// this next check seems unlikely
if(! (HttpContext.Current.Session == null))
{
// pass HttpContext.Current.Session["APP_Path"].ToString() as a parameter
if (!(String.IsNullOrEmpty(HttpContext.Current.Session["APP_Path"].ToString())))// set in Global.asax.cs Start_Session
exporter.Arguments.Add(exporter.Arguments.Count, HttpContext.Current.Session["APP_Path"].ToString()); // to last parameter position
else
exporter.Arguments.Add(exporter.Arguments.Count, String.Empty); // or nothing to last parameter position
// end change
}
exporter.Arguments 存放我的报告的参数。 您的情况无疑会有所不同。 有一点很重要的是,将此参数始终放在首位或始终放在最后,这样其他参数就不会被它搞砸了。在报告本身中对参数使用相同的顺序。参数显然是按名称关联值,但我认为将它们混搭是一个坏主意,最终会造成混淆。
3) 现在您可以独立运行报告,当提示您输入网站 URL 词干时,您输入 file://。当在网络上运行相同的确切报告时,应用程序会发送它,无论网站主干是什么,但类似于 http://localhost/website/ 。
问题:
1) 在开发过程中,在报告中显示您的变量。确保对于缩略图,您始终使用服务器相关但完整的 Windows/DOS 路径,对于图片,在开发过程中使用 file:// 的完整 Windows/DOS 路径
您始终可以在制作前隐藏它们。
2) 注意过多的斜杠等。很容易以双斜杠结束,从而搞砸 URL...
3) 请记住,Crystal 以某种神秘的顺序评估公式,但我知道页眉是在细节之前处理的。我把我所有的公共变量,即 DocRoot 和 WebSiteRootURL 都放在 Page Header 中(甚至是 Report Header,因为它们不会改变),所以它们首先被量化,细节带可以使用它们。
4) 我将所有图片展示和列表委托给嵌入式子报表。它使用 Shared StringVar xyz 方法共享所需的变量。这有点松鼠,但基本上子报告总是从容器报告中获取它的值,用于常见的东西(见上面的评论 3)。为了布置该子报表,我制作了一个更小的子报表作为公共变量的持有者,这样我就不必运行整个怪物。
5) 这些“变量持有者”报告无法被抑制,或者这些值似乎无法解析。所以让它们变得非常小和无边界,然后压扁页眉或任何隐藏它们的东西。我想文本和背景也可以设置为相同以进一步隐藏它们,但在您完成布局等操作之前不要这样做,否则您将不得不四处寻找小报告。它们是您的本地内存变量。
6) 独立文件中的图像/文档/链接文件必须使用传统的 DOS/Windows 文件名路径(无正斜杠)。这些可以为网站解析,但要建立一个超链接,斜线必须向前,据我所知,所以假设你必须翻转。
7) 作为旁注,我能够在开发过程中通过使用 Junction Magic 将 ~/MyDocuments 重新映射到 D:\MyDocuments 等,将我的文档从网站层次结构中重新定位。网络服务器似乎并不关心这一点它实际上是遍历 D:\MyDocuments 但认为它位于网站的子文件夹中。但是,您可能必须使用虚拟目录方法 - 请注意。或者,将文档存储在网站下方,但不知何故,这似乎很笨拙。
8) 我有提到权限问题吗?不,但他们可能会咬你。确保 IIS_IUSR 和任何可以访问文件/文件夹等的东西。
9) 这一切不应该容易得多吗?哦,好吧,还是谢谢你 SAP...
新闻爆炸 -
显然 Request 对象也包含网站 URL 词干。如果您不想走全球路线,请使用它。
另外,我可能没有明确说明,但是 CR OLE 对象只理解 Windows……而不是 unix 文件名约定。作为进一步的考虑,路径长度必须符合。
最后,当我在网页上显示文件名时,我隐藏了 DOS/Windows 根目录和网站主干,只显示相对路径,例如~/Folder/Folder/File.png 这样文档在网站上的排列方式就不太明显了 - 可能是不必要的偏执,但也有好处,如果网站移动用户不会感到困惑。
问题可能会或可能不会得到答案。玩得开心。