﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web报表工具-专业博客 &#187; Web报表</title>
	<atom:link href="http://reportblog.cn/archives/tag/web%e6%8a%a5%e8%a1%a8/feed" rel="self" type="application/rss+xml" />
	<link>http://reportblog.cn</link>
	<description>报表技术知识：web报表，报表工具，表单工具，报表设计，报表系统，java报表</description>
	<lastBuildDate>Wed, 25 Apr 2012 03:18:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>“Java+POI+模板”打造复杂Excel 报表</title>
		<link>http://reportblog.cn/archives/1760</link>
		<comments>http://reportblog.cn/archives/1760#comments</comments>
		<pubDate>Wed, 25 Apr 2012 03:17:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web报表工具-专业知识]]></category>
		<category><![CDATA[Web报表]]></category>

		<guid isPermaLink="false">http://reportblog.cn/?p=1760</guid>
		<description><![CDATA[做的Struts 项目中有这样的功能，用户可以将数据导出到Excel 报表，如图1 所示。 &#160; 1 设计思路 Java 对于Excel 的操作一般借助于POI 类库，由于该报表的表头比较复杂，直接用POI 控制报表的生成比较困难，这时可以先制作Excel 报表模板，而后再通过Java 调用POI 函数将用户数据写入到Excel 报表模板，最后导出到新的目标文件即可。 2 设计步骤 2.1 Excel 报表模板 根据需要设计出Excel 报表，并保存为report.xls。该报表有复杂的表头，报表第4 行为合计行，用于对所有数值型列的各行数据进行汇总，如图1 所示。 2.2 Struts 的动作执行函数ExcelExportAction 该Action 函数在用户需要执行报表导出时通过Struts 页面调用或用户触发执行。 package com.tj.struts.action; import java.io.FileOutputStream; import javax.servlet.http.*; import org.apache.struts.action.*; import databaseUtil.ExcelPoi; public class ExcelExportAction extends Action { public ActionForward execute ( ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse [...]]]></description>
			<content:encoded><![CDATA[<p align="left">做的Struts 项目中有这样的功能，用户可以将数据导出到Excel 报表，如图1 所示。<span id="more-1760"></span></p>
<div class="wp-caption alignnone" style="width: 559px"><img title="报表样式图" src="http://www.finereport.com//forumimages/j-report%20sample.jpg" alt="报表样式图" width="549" height="164" /><p class="wp-caption-text">报表样式图</p></div>
<p>&nbsp;</p>
<p align="left">1 设计思路</p>
<p align="left">Java 对于Excel 的操作一般借助于POI 类库，由于该<a href="http://www.finereport.com/">报表</a>的表头比较复杂，直接用POI 控制<a href="http://www.finereport.com/">报表</a>的生成比较困难，这时可以先制作Excel <a href="http://www.finereport.com/knowledge/design">报表模板</a>，而后再通过Java 调用POI 函数将用户数据写入到Excel <a href="http://www.finereport.com/knowledge/design">报表模板</a>，最后导出到新的目标文件即可。</p>
<p>2 设计步骤</p>
<p align="left">2.1 Excel 报表模板</p>
<p align="left">根据需要设计出Excel <a href="http://www.finereport.com/">报表</a>，并保存为report.xls。该<a href="http://www.finereport.com/">报表</a>有复杂的表头，<a href="http://www.finereport.com/">报表</a>第4 行为合计行，用于对所有数值型列的各行数据进行汇总，如图1 所示。</p>
<p align="left">2.2 Struts 的动作执行函数ExcelExportAction</p>
<p align="left">该Action 函数在用户需要执行<a href="http://www.finereport.com/">报表</a>导出时通过Struts 页面调用或用户触发执行。</p>
<p align="left">package com.tj.struts.action;</p>
<p align="left">import java.io.FileOutputStream;</p>
<p align="left">import javax.servlet.http.*;</p>
<p align="left">import org.apache.struts.action.*;</p>
<p align="left">import databaseUtil.ExcelPoi;</p>
<p>public class ExcelExportAction extends Action {</p>
<p align="left">public ActionForward execute ( ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)</p>
<p align="left">throws Exception {</p>
<p align="left">//执行SQL 获得输出到报表的数据</p>
<p align="left">String sql=” select * fron project” ;</p>
<p align="left">//准备输出的报表路径，及文件名</p>
<p align="left">String outputfile =” c:\\output.xls” ;</p>
<p align="left">//制作好的报表模板存放路径</p>
<p align="left">String templatefile=” c:\\report.xls” ;</p>
<p align="left">//模板的列数为39</p>
<p align="left">int column=39;</p>
<p align="left">try {</p>
<p align="left">//实例化具体的业务处理类ExcelPoi</p>
<p align="left">ExcelPoi pd = new ExcelPoi (colnum) ;</p>
<p align="left">//getExcelSheet 以sql 为参数执行查询，将查询数据写入模版文件“templatefile”的当前工作簿的选定工作表pd.getExcelSheeet (sql,templatefile) ;</p>
<p align="left">// 新建以文件outputfile 为目标的输出文件流</p>
<p align="left">FileOutputStream fos = new FileOutputStream (outputfile) ;</p>
<p align="left">//将工作簿写入输出文件流，得到输出报表文件</p>
<p align="left">pd.exportExcel (fos) ;</p>
<p align="left">} catch (Exception e) {</p>
<p align="left">e.printStackTrace () ;</p>
<p align="left">} finally {</p>
<p align="left">try {fos.close () ;</p>
<p align="left">} catch (Exception e) {</p>
<p align="left">e.printStackTrace () ;</p>
<p align="left">}}</p>
<p align="left">return mapping.findForward (” success”) ;</p>
<p align="left">}}</p>
<p align="left">2.3 设计业务处理类ExcelPoi</p>
<p align="left">package databaseUtil;</p>
<p align="left">import java.io.*;</p>
<p align="left">import java.sql.*;</p>
<p align="left">import java.util.*;</p>
<p align="left">import org.apache.poi.hssf.usermodel.*;</p>
<p align="left">public class ExcelPoi {</p>
<p align="left">private int columNumber = 0;</p>
<p align="left">private int cellNumber=0;</p>
<p align="left">private HSSFWorkbook workbook = null;</p>
<p align="left">private HSSFSheet worksheet=null;</p>
<p align="left">public ExcelPoi (int columNumber)</p>
<p align="left">{this.columNumber=columNumber;}</p>
<p align="left">&lt;! —sql：传入参数，实现输出数据查询，templatefile：传入参数，Excel 模板的存放路径&#8211;&gt;</p>
<p align="left">public void getExcelSheeet ( String sql,String templatefile)</p>
<p align="left">throws SQLException</p>
<p align="left">{try {</p>
<p align="left">//新建以文件templatefile 为源文件的输文件流，而后从中取得模板文件templatefile 的当前工作簿</p>
<p align="left">workbook = new HSSFWorkbook ( new FileInputStream</p>
<p align="left">(templatefile)) ;</p>
<p align="left">} catch (FileNotFoundException e) {</p>
<p align="left">e.printStackTrace () ;</p>
<p align="left">} catch (IOException e) {</p>
<p align="left">e.printStackTrace () ;}</p>
<p align="left">//取得当前工作簿中的“天津大学工程项目库管理系统”工作表</p>
<p align="left">worksheet=workbook.getSheet (” 天津大学工程项目库管</p>
<p align="left">理系统”) ;</p>
<p align="left">//载入数据库驱动，获得数据库的连接，数据库名为tj，用户名swm， 密码adminClass.forName ( ” com.microsoft.jdbc.sqlserver.SQLServerDriver”) .newInstance () ;</p>
<p align="left">dbConn = DriverManager.getConnection (” jdbc:microsoft:</p>
<p align="left">sqlserver://localhost:1433;DatabaseName =tj” , ” swm” , “</p>
<p align="left">admin”) ;</p>
<p align="left">statement = dbConn.createStatement (ResultSet.</p>
<p align="left">TYPE_SCROLL_INSENSITIVE,ResultSet.</p>
<p align="left">CONCUR_UPDATABLE) ;</p>
<p align="left">//以SQL 为参数，执行数据查询</p>
<p align="left">ResultSet rs = statement.executeQuery (sql) ;</p>
<p align="left">int rowIndex = 4;</p>
<p align="left">while (rs.next ())</p>
<p align="left">{ List list = new ArrayList () ;</p>
<p align="left">//将查询得到的每行数据放入list 中</p>
<p align="left">for (int i = 1;i &lt;= columNumber;i++)</p>
<p align="left">{list.add (rs.getString (i)) ; }</p>
<p align="left">//调用createTableRow 把list 中数据写入worksheet 的第rowIndex 行</p>
<p>createTableRow (worksheet,list, (short) rowIndex) ;</p>
<p>rowIndex++;}}</p>
<p align="left">&lt;! —-用list 数据创建当前工作表的第rowIndex 行，并将该行非String 数据累加到合计行行&#8211;&gt;</p>
<p align="left">public void createTableRow ( HSSFSheet worksheet1,List list,short rowIndex)</p>
<p align="left">{//getRow (3) 取得工作表的第四行，即合计行（行数从0 开始）</p>
<p align="left">HSSFRow sumrow = worksheet1.getRow (3) ;</p>
<p align="left">for (short i = 0;i &lt; list.size () ;i++)</p>
<p align="left">{ HSSFCell cell = sumrow.getCell (i) ;</p>
<p align="left">//将list 中1、2、3、4、6、7、8 列之外（这几列为String 类型不进行合计），其它列数据累加到合计行的对应列单元中</p>
<p align="left">if (! (i==0||i==1||i==2||i==3||i==5||i==6||i==7)) {</p>
<p align="left">cell.setCellValue ( list.getNumericCellValue ( ) + ( double)</p>
<p align="left">Integer.parseInt ((String) list.get (i))) ;</p>
<p align="left">}}</p>
<p align="left">//创建当前工作表的新行，等待放入数据</p>
<p align="left">HSSFRow row = worksheet1.createRow ( ( short)rowIndex) ;</p>
<p align="left">//在新创建行中创建各列单元格，并将list 中对应数据写入</p>
<p align="left">for (short i = 0;i &lt; list.size () ;i++)</p>
<p align="left">{HSSFCell cell = row.createCell ((short) i) ;</p>
<p align="left">cell.setEncoding (HSSFCell.ENCODING_UTF_16) ;</p>
<p align="left">cell.setCellValue ((String) list.get (i)) ; }</p>
<p align="left">&lt;! &#8211;该函数将存储了数据的模板文件导出到输出文件流，创建一个新的报表&#8211;&gt;</p>
<p align="left">public void exportExcel ( OutputStream os) throws</p>
<p align="left">IOException</p>
<p align="left">{worksheet.setGridsPrinted (true) ;</p>
<p align="left">workbook.write (os) ;</p>
<p align="left">}}</p>
<p align="left">3 结语</p>
<p align="left">对于一些要求非常苛刻的<a href="http://www.finereport.com/">报表</a>输出可以借助于一些第三方插件，比如<a href="http://www.finereport.com/knowledge/aquire/crystalreport.html">水晶报表</a>等。在实际中可以随心所欲地构建<a href="http://www.finereport.com/knowledge/design">报表模板</a>，而后通过程序控制将需要导出的数据导出到<a href="http://www.finereport.com/">报表</a>中，关键在于如何精确地控制数据导出的位置，保证数据在<a href="http://www.finereport.com/">报表</a>中的准确的位置，这是需要格外注意的。</p>

<p><strong>Web报表主题相关文章：</strong></p>
<ul>
<li><a href="http://reportblog.cn/archives/1424">Web报表工具中自定义函数概述</a></li>
<li><a href="http://reportblog.cn/archives/872">finereport报表软件设计概述</a></li>
<li><a href="http://reportblog.cn/archives/802">理解FineReport缓存系列1——数据集缓存</a></li>
<li><a href="http://reportblog.cn/archives/805">理解FineReport缓存系列2——数据集共享</a></li>
<li><a href="http://reportblog.cn/archives/217">论类Excel报表设计器标准</a></li>
</ul><br />
]]></content:encoded>
			<wfw:commentRss>http://reportblog.cn/archives/1760/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web报表FineReport通过权限控制数据访问方案</title>
		<link>http://reportblog.cn/archives/1472</link>
		<comments>http://reportblog.cn/archives/1472#comments</comments>
		<pubDate>Mon, 21 Nov 2011 02:26:40 +0000</pubDate>
		<dc:creator>FineReport——web报表技术领跑者</dc:creator>
				<category><![CDATA[Web报表工具-技术园地]]></category>
		<category><![CDATA[finereport报表]]></category>
		<category><![CDATA[Web报表]]></category>
		<category><![CDATA[控制数据访问]]></category>

		<guid isPermaLink="false">http://reportblog.cn/?p=1472</guid>
		<description><![CDATA[问题：实际应用环境中，不同角色的人可能对数据具有不同的访问权限，通过直接在SQL语句中筛选出需要的数据制作模板可以解决该需求，但对于角色较多的情况，就需要制作很多张样式相同只是数据集不同的报表，不利于后期的维护并且加大了报表制作的工作量。 方案：针对该问题，在Web报表FineReport中，可以利用SQL参数配合参数处理器再结合权限以完成该需求。使用该方案只需要制作一张表样，利用SQL中的参数进行动态过滤达到该目的。下面具体描述该方案的实施过程。 第一步：数据准备 这里使用的是DEMO数据，主要为了演示该方案的操作，具体使用的时候需要根据具体的数据情况进行调整： 表：datas ID DATA ROLE 1 100 0 2 200 0 3 300 0 4 400 1 5 500 1 6 600 2 7 700 2 8 800 3 ID：编号 DATA：数据 ROLE：可查看角色编码 表：roles ID ROLENANME ROLE 1 总裁 0 2 总经理 1 3 部门经理 2 4 销售人员 3 第二步：制作模板 2.1 新建一张模板，报表数据集中新建一个“数据库查询数据集”，名称为：datas，SQL语句写成“select * [...]]]></description>
			<content:encoded><![CDATA[<p><strong>问题</strong>：实际应用环境中，不同角色的人可能对数据具有不同的访问权限，通过直接在SQL语句中筛选出需要的数据制作模板可以解决该需求，但对于角色较多的情况，就需要制作很多张样式相同只是数据集不同的<a title="报表" href="http://www.finereport.com/">报表</a>，不利于后期的维护并且加大了<a title="报表制作" href="http://www.finereport.com/knowledge/professional/webreport.html">报表制作</a>的工作量。<br />
<strong>方案</strong>：针对该问题，在<a title="web报表" href="http://www.finereport.com/knowledge/professional/webreport.html">Web报表</a>FineReport中，可以利用SQL参数配合参数处理器再结合权限以完成该需求。使用该方案只需要制作一张表样，利用SQL中的参数进行动态过滤达到该目的。下面具体描述该方案的实施过程。<span id="more-1472"></span></p>
<p><strong>第一步：数据准备</strong><br />
这里使用的是DEMO数据，主要为了演示该方案的操作，具体使用的时候需要根据具体的数据情况进行调整：<br />
表：datas</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="197">ID</td>
<td valign="top" width="197">DATA</td>
<td valign="top" width="197">ROLE</td>
</tr>
<tr>
<td valign="top" width="197">1</td>
<td valign="top" width="197">100</td>
<td valign="top" width="197">0</td>
</tr>
<tr>
<td valign="top" width="197">2</td>
<td valign="top" width="197">200</td>
<td valign="top" width="197">0</td>
</tr>
<tr>
<td valign="top" width="197">3</td>
<td valign="top" width="197">300</td>
<td valign="top" width="197">0</td>
</tr>
<tr>
<td valign="top" width="197">4</td>
<td valign="top" width="197">400</td>
<td valign="top" width="197">1</td>
</tr>
<tr>
<td valign="top" width="197">5</td>
<td valign="top" width="197">500</td>
<td valign="top" width="197">1</td>
</tr>
<tr>
<td valign="top" width="197">6</td>
<td valign="top" width="197">600</td>
<td valign="top" width="197">2</td>
</tr>
<tr>
<td valign="top" width="197">7</td>
<td valign="top" width="197">700</td>
<td valign="top" width="197">2</td>
</tr>
<tr>
<td valign="top" width="197">8</td>
<td valign="top" width="197">800</td>
<td valign="top" width="197">3</td>
</tr>
</tbody>
</table>
<p>ID：编号<br />
DATA：数据<br />
ROLE：可查看角色编码</p>
<p>表：roles</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="197">ID</td>
<td valign="top" width="197">ROLENANME</td>
<td valign="top" width="197">ROLE</td>
</tr>
<tr>
<td valign="top" width="197">1</td>
<td valign="top" width="197">总裁</td>
<td valign="top" width="197">0</td>
</tr>
<tr>
<td valign="top" width="197">2</td>
<td valign="top" width="197">总经理</td>
<td valign="top" width="197">1</td>
</tr>
<tr>
<td valign="top" width="197">3</td>
<td valign="top" width="197">部门经理</td>
<td valign="top" width="197">2</td>
</tr>
<tr>
<td valign="top" width="197">4</td>
<td valign="top" width="197">销售人员</td>
<td valign="top" width="197">3</td>
</tr>
</tbody>
</table>
<p><strong>第二步：制作模板</strong><br />
2.1 新建一张模板，<a title="报表" href="http://www.finereport.com">报表</a>数据集中新建一个“数据库查询数据集”，名称为：datas，SQL语句写成“select * from datas where ROLE&gt;=[?ROLE?]”<br />
2.2 拖拽新建的<a title="报表" href="http://www.finereport.com/">报表</a>数据集datas的数据列至<a title="报表" href="http://www.finereport.com/">报表</a>中，如下图所示：<br />
<a title="http://www.finereport.com/forumimages/tgqxkzsjfw1.jpg" href="http://www.finereport.com/forumimages/tgqxkzsjfw1.jpg"><img class="alignnone" src="http://www.finereport.com/forumimages/tgqxkzsjfw1.jpg" alt="" width="693" height="212" /></a><br />
2.3 新建一个服务器数据字典，用于进行角色名称与角色编码的转换，因为这里是演示用，就直接将数据写死了，使用自定义的服务器数据字典，用户可以根据具体的情况使用数据库查询数据字典来定义，关键点是要将“角色名”设置为key，“角色编码”设置为value。因为在应用的过程中，一个用户的角色是通过角色名来定义的，而对数据的访问控制是通过角色编码来控制的，这里需要一个值转换的过程。如果角色名与角色编码一致则可以不经过下列步骤的设置。<br />
数据字典的名称为:roles_map</p>
<p><a title="http://www.finereport.com/forumimages/tgqxkzsjfw2.jpg" href="http://www.finereport.com/forumimages/tgqxkzsjfw2.jpg"><img class="alignnone" src="http://www.finereport.com/forumimages/tgqxkzsjfw2.jpg" alt="" width="780" height="220" /></a></p>
<p>2.4 设置参数处理器，选择菜单中的“<a title="报表" href="http://www.finereport.com/">报表</a>”-“参数处理器”，定义先前SQL语句中定义的参数“ROLE”的参数处理器，这里采用公式类型，用于将角色名处理为角色编码，公式为：“MAP($ROLE,”roles_map”)”如下图所示：</p>
<p><a title="http://www.finereport.com/forumimages/tgqxkzsjfw3.jpg" href="http://www.finereport.com/forumimages/tgqxkzsjfw3.jpg"><img class="alignnone" src="http://www.finereport.com/forumimages/tgqxkzsjfw3.jpg" alt="" width="400" height="360" /></a><br />
2.5 保存模板文件即可。<br />
2.6 用户在集成应用的时候，需要在系统登录后设置当前登录的用户的角色，或者使用FineReport自带的权限管理系统。如果采用FineReport自带的权限管理系统，上述SQL语句中的ROLE参数可使用FR_ROLE_NAME来替代，该参数是FineReport权限系统中的默认登录角色参数名。具体登录角色设置方式请参见FineReport权限集成帮助文档或咨询FineReport服务人员。</p>

<p><strong>Web报表主题相关文章：</strong></p>
<ul>
<li><a href="http://reportblog.cn/archives/1741">Apache和tomcat整合</a></li>
<li><a href="http://reportblog.cn/archives/1700">IIS集成配置</a></li>
<li><a href="http://reportblog.cn/archives/1697">Jboss 服务器 JNDI 配置数据源连接数据库</a></li>
<li><a href="http://reportblog.cn/archives/1694">Oracle 数据库实现自增长列</a></li>
<li><a href="http://reportblog.cn/archives/1689">Weblogic 10.1 配置JNDI 数据源</a></li>
</ul><br />
]]></content:encoded>
			<wfw:commentRss>http://reportblog.cn/archives/1472/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

