用服务器组件解决WEB交叉报表问题(2)

原创 2007年09月18日 17:33:00

用服务器组件解决WEB交叉报表问题
——修改FastReport源码,支持内存流导出

 

Fast Report是一个经典的报表控件,不过其导出功能只支持导出到磁盘文件,而此项目为了避开权限的限制和出于服务器安全的需要,要求将Fast Report生成的报表导出到内存流,所以要修改Fast Report源码。{========================================================================
  DESIGN BY :  彭国辉
  DATE:        2007-09-15
  SITE:       
http://kacarton.yeah.net/
  BLOG:        http://blog.csdn.net/nhconch
  EMAIL:       kacarton[A T]sohu.com  文章为作者原创,转载请注明文章出处、保留作者信息,谢谢支持!
=========================================================================}

Fast Report2.5的导出函数在FR_Class文件中声明,参考此函数,可以很轻易的写出导出到内存流的函数:
//添加导出到内存流的支持 --Conch 2007-09-10--
procedure TfrReport.ExportToStream(Filter: TfrExportFilter; Stream: TMemoryStream);
var
  s: String;
  Flag, NeedConnect: Boolean;
begin
  DocMode := dmPrinting;
  FCurrentFilter := Filter;
  if (Preview <> nil) and (EMFPages.Count = 0) then
  begin
    Preview.Disconnect;
    NeedConnect := True;
 
end
  else

    NeedConnect := False;
{========================================================================
  DESIGN BY :  彭国辉
  DATE:        2007-09-15
  SITE:       
http://kacarton.yeah.net/
  BLOG:        http://blog.csdn.net/nhconch
  EMAIL:       kacarton[A T]sohu.com  文章为作者原创,转载请注明文章出处、保留作者信息,谢谢支持!
=========================================================================}

  Flag := True;
  if Assigned(FCurrentFilter.OnBeforeExport) then
    FCurrentFilter.OnBeforeExport(FCurrentFilter.FileName, Flag);
    FCurrentFilter.Stream := Stream;

      CurReport := Self;
      MasterReport := Self;
      SavedAllPages := EMFPages.Count;

      FCurrentFilter.OnBeginDoc;
        ExportBeforeModal(Self);

    if Assigned(FCurrentFilter.OnAfterExport) then
      FCurrentFilter.OnAfterExport(FCurrentFilter.FileName);

  if NeedConnect then
    Preview.Connect(Self);
  FCurrentFilter := nil;
end;

同样,TfrHTML2Export控件是将CSS文件与HTML分开保存的,这样使得内存流中的HTML内容因缺少CSS而无法显示,故此要修改TfrHTML2Export.OnEndDoc函数。从该函数中找到SaveStringToFile(ImageFolderFull + '/' + CSSFile, s)这一句(FR2.5在第461行),改为:
    if FileName <> '' then
      SaveStringToFile(ImageFolderFull + '/' + CSSFile, s)
    else begin
      s := '<style type=''text/css''>' + LF + s + LF + '</style>' + LF;
      Stream.Write(s[1], Length(s));
    end;
{========================================================================
  DESIGN BY :  彭国辉
  DATE:        2007-09-15
  SITE:       
http://kacarton.yeah.net/
  BLOG:        http://blog.csdn.net/nhconch
  EMAIL:       kacarton[A T]sohu.com  文章为作者原创,转载请注明文章出处、保留作者信息,谢谢支持!
=========================================================================}
其它版本或其它导出控件可按此方法修改(导出Excel控件因使用OLE技术调用Excel组件,只能保存到磁盘文件),修改后的OnEndDoc函数如下:
procedure TfrHTML2Export.OnEndDoc;
var
  s             : string;
  i, j          : integer;
  Page          : THPage;
  LastBottom    : integer;
  CSSFile       : string;
  CSSFilePrint  : string;
  NavFile       : string;
//  DefaultStyle : THStyle;
//  Style        : THStyle;
  h1, h2        : string;
  MaxWidth      : integer;
  MinLeftMargin : integer;

begin
  if Navigator = nil then Exit;
  if FPages.Count = 0 then Exit;

  if FStyles.Count > 0 then
  begin
    s := '';
    CSSFilePrint := ChangeFileExt(ExtractFileName(FileName), '_print.css');

    if Navigator.Position <> [] then
      s := s + Navigator.GetStyleHTML(true);

    if s <> '' then
      SaveStringToFile(ImageFolderFull + '/' + CSSFilePrint, s);
    {----------------------------}

    CSSFile := ChangeFileExt(ExtractFileName(FileName), '.css');

    {DefaultStyle := nil;
    for i := 0 to FStyles.Count - 1 do
    begin
      Style := THStyle(FStyles[i]);
      if not (Style is THStyleFrame) or
        (THStyleFrame(Style).FFillColor = $1FFFFFFF) then
        if (DefaultStyle = nil) or (Style.FCount > DefaultStyle.FCount) then
          DefaultStyle := THStyle(FStyles[i]);
    end;

    if DefaultStyle <> nil then
      DefaultStyle.SetDefault;}

    //s := 'img' + LF + '{' + LF + 'border: 0px solid #000000;' + LF + '}' + LF;

    s := 'span' + LF + '{' + LF + 'position: absolute;' + LF + '}' + LF +
      'img' + LF + '{' + LF + 'position: absolute;' + LF + '}' + LF +
      '.page_break' + LF + '{' + LF + 'page-break-before: always;' + LF + '}' + LF;

    for i := 0 to FStyles.Count - 1 do
      s := s + THStyle(FStyles[i]).GetHtml + LF;

    if {(FPages.Count > 1) and} (Navigator.Position <> []) then
      s := s + Navigator.GetStyleHTML(false);
    //配合导出到内存流功能,将CSS内容直接写到流中 --Conch--
    if FileName <> '' then
      SaveStringToFile(ImageFolderFull + '/' + CSSFile, s)
    else begin
      s := '<style type=''text/css''>' + LF + s + LF + '</style>' + LF;
      Stream.Write(s[1], Length(s));
    end;
    {----------------------------}
  end;

  if FMultiPage and (FNavigator.Position <> []) then
  begin
    if Navigator.InFrame and Navigator.WideInFrame then
    begin
      MaxWidth := Screen.Width - 20;
      MinLeftMargin := 0;
    end
    else begin
      MaxWidth := 0;
      MinLeftMargin := High(integer);
      for j := 0 to FPages.Count - 1 do
      begin
        Page := THPage(FPages[j]);
        if Page.Width - Page.RightMargin > MaxWidth then
          MaxWidth := Page.Width - Page.RightMargin;
        if Page.LeftMargin < MinLeftMargin then
          MinLeftMargin := Page.LeftMargin;
      end;
      if MaxWidth + MinLeftMargin > Screen.Width then
        MaxWidth := Screen.Width - MinLeftMargin;
    end;

    FNavigator.BuildItems(MaxWidth);

    if FNavigator.InFrame then
    begin
      NavFile := ChangeFileExt(ExtractFileName(FileName), '') + '_' +
        NavigatorFilePostfix + '_0.html';
      if npTop in Navigator.Position then
        h1 := Format('%dpx,', [Navigator.GetHeight])
      else
        h1 := '';

      if npBottom in Navigator.Position then
        h2 := Format(', %dpx', [Navigator.GetHeight])
      else
        h2 := '';

      s := Format(HTMLHeader, [CurReport.Title, CSSFile, CSSFilePrint]) +
        Format('<frameset rows="%s *%s" framespacing="0" frameborder="0" border="0">',
          [h1, h2]) + LF;

      if npTop in Navigator.FPosition then
        s := s + Format('<frame src="%s" name="NAVIGATOR_TOP" scrolling="no" ' +
          'marginwidth="0" marginheight="0">', [ImageFolder + '/' + NavFile]) + LF;

      s := s + Format('<frame src="%s" name="%s" scrolling="yes" marginwidth="0" ' +
        'marginheight="0">', [ImageFolder + '/' + THPage(FPages[0]).GetName,
        PageFrame]) + LF;

      if npBottom in Navigator.FPosition then
        s := s + Format('<frame src="%s" name="NAVIGATOR_BOTTOM" scrolling="no" ' +
          'marginwidth="0" marginheight="0">', [ImageFolder + '/' + NavFile]) + LF;

      s := s + '</frameset>' + LF + HTMLFooter;
      Stream.Write(s[1], Length(s));

      for j := 0 to FNavigator.FItems.Count - 1 do
      begin
        s := Format(HTMLHeader, [CurReport.Title, CSSFile, CSSFilePrint]);
        s := s + Navigator.GetHTML(TNavigatorItem(FNavigator.FItems[j]).MinPage,
          0, MinLeftMargin, MaxWidth, true) + HTMLFooter;
        NavFile := ChangeFileExt(ExtractFileName(FileName), '') + '_' +
          NavigatorFilePostfix + '_' + IntToStr(j) + '.html';
        SaveStringToFile(ImageFolderFull + '/' + NavFile, s);
      end;
    end;
  end;

  LastBottom := 5;
  for j := 0 to FPages.Count - 1 do
  begin
    Page := THPage(FPages[j]);

    if FMultiPage then
    begin
      if (j = 0) and (not Navigator.InFrame or (Navigator.Position = [])) then
        s := Format(HTMLHeader, [CurReport.Title, ImageFolder + '/' + CSSFile,
          ImageFolder + '/' + CSSFilePrint])
      else
        s := Format(HTMLHeader, [CurReport.Title, CSSFile, CSSFilePrint]);

      LastBottom := 5;
      if (FNavigator.Position <> []) and FNavigator.InFrame then
      begin
        s := s + Page.GetHTML(LastBottom, 0) + HTMLFooter;  //!!!!!!!!!!!!!!!!!!!!
        SaveStringToFile(ImageFolderFull + '/' + Page.GetName, s);
      end
      else begin
        if (FPages.Count > 1) and (npTop in Navigator.Position) then
        begin
          s := s + Navigator.GetHTML(Page.ID, LastBottom, Page.LeftMargin,
            Page.Width - Page.RightMargin, false);
          Inc(LastBottom, Navigator.GetHeight + 15);
        end;

        s := s + Page.GetHTML(LastBottom, 0);

        if (FPages.Count > 1) and (npBottom in Navigator.Position) then
          s := s + Navigator.GetHTML(Page.ID, Page.Height + LastBottom +
            {Page.BottomMargin} + 5, Page.LeftMargin, Page.Width - Page.RightMargin, false);

        s := s + HTMLFooter;

        if j = 0 then
          Stream.Write(s[1], Length(s))
        else
          SaveStringToFile(ImageFolderFull + '/' + Page.GetName, s);
      end;
    end
    else begin
      s := Page.GetHTML(LastBottom, 0);
      if j = 0 then
        s := Format(HTMLHeader, [CurReport.Title, ImageFolder + '/' + CSSFile,
          ImageFolder + '/' + CSSFilePrint]) + s;
      Stream.Write(s[1], Length(s));
      Inc(LastBottom, Page.Height);
    end;
  end;

  if not FMultiPage then
  begin
    s := HTMLFooter;
    Stream.Write(s[1], Length(s));
  end;

  ClearListWithFree(FNavigator.FItems);
  ClearListWithFree(FStyles);
  ClearListWithFree(FPages);
end;
{========================================================================
  DESIGN BY :  彭国辉
  DATE:        2007-09-15
  SITE:       
http://kacarton.yeah.net/
  BLOG:        http://blog.csdn.net/nhconch
  EMAIL:       kacarton[A T]sohu.com  文章为作者原创,转载请注明文章出处、保留作者信息,谢谢支持!
=========================================================================}

经修改后就可以直接用FrReport1.ExportToStream(ex{TfrHTML2Export}, Stream{TMemoryStream});将报表导出到内存流了。

上一篇:用服务器组件解决WEB交叉报表问题(1)

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

交叉报表列头排序时遇到的oracle问题—oracle ORA-12704:字符集不匹配、varchar2转化为nvarchar2字符缺失、case when else后的字符类型要一致

在做交叉报表列头的排序时,遇到这三个问题,下面具体来说一下。 设计的数据库的表结构如图1所示: 图1 要处出来student_name_,s.grade_,s.subject_name_,这...

JFreeChart基于Java Web的报表组件的使用以及解决乱码

JFreeChart的简介在此就不赘述,主要讲解如何使用JFreeChart创建各种图表,这些图表包括:饼图、柱状图 ( 普通柱状图以及堆栈柱状图 )、线图、区域图、分布图、混合图、甘特图以及一些仪表...

软件开发工程师(JAVA)中级考试大纲之--五 J2EE WEB高级组件开发--(三)Tomcat服务器的环境及配置;应用发布和数据源配置;

首先定义tomcat6的安装根目录为 ${CATALINA_HOME} 在tomcat6版本中,context元素已经从server.xml文件中独立出来了,放在一个context.xml文件中。因...

一个Web报表项目的性能分析和优化实践(二):MySQL数据库连接不够用(TooManyConnections)问题的一次分析和解决案例

MySQL数据库连接不够用(TooManyConnections)问题的一次分析和解决案例

mac下交叉编译protobuf静态库。解决protobuf在iPhone 5s,iPad air,iPad mini2上crash的问题。

背景 项目中使用protobuf作为网络传输协议,最开始在项目中直接使用源代码编译,在真机上测试一直是正常的,直到某天开始在64bit cpu的设备上发现protobuf导致crash了,于是就开始...
  • maxway
  • maxway
  • 2013-12-26 01:27
  • 3694

ssh三大框架简单整合,struts2整合JasperReport报表、图表,解决HTML显示图片不出来,PDF中文不显示的问题

ssh三大框架简单整合,struts2整合JasperReport报表,解决HTML显示图片不出来,PDF中文不显示的问题
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)