flex前端数据导出至Excel


1.客户端导出Excel
1.1 网上找了些资料,目前的jar包有应用于桌面系统的as3xls,AirExcel,在web应用中无法导入相关类包。
1.2 使用js调用客户端的Excel 对象。在网上找的一段代码:
// ACTION SCRIPT FOR YOUR FLEX APP
function doCopy(dg)
{
var font = dg.getStyle('fontFamily');
var size = dg.getStyle('fontSize');
var hcolor ;
if(dg.getStyle("headerColor") != undefined) hcolor = [dg.getStyle("headerColor")];
else hcolor = dg.getStyle("headerColors");
var str:String = '<html><body><table width="'+dg.width+'"><thead><tr width="'+         dg.width+'" style="background-color:#' +Number((hcolor[0])).toString(16)+'">';
for(var i=0;i<dg.__columns.length;i++)
{
var colors = dg.getStyle("themeColor");
var style = 'style="font-family:'+font+';font-size:'+size+'pt;"';
if(dg.__columns[i].headerText != undefined)
{
str+="<th "+style+">"+dg.__columns[i].headerText+"</th>";
}
else
{
str+= "<th "+style+">"+dg.__columns[i].columnName+"</th>";
}
}
str += "</tr></thead><tbody>";
var colors = dg.getStyle("alternatingRowColors");
for(var j=0;j<dg.length;j++)
{
str+="<tr width=\""+Math.ceil(dg.width)+"\" style='background-color:#" +Number((colors[j%colors.length])).toString(16)+"'>";
var style = 'style="font-family:'+font+';font-size:'+size+'pt;"';
for(var i=0;i<dg.__columns.length;i++)
{
if(dg.getItemAt(j) != undefined && dg.getItemAt(j) != null)
if(dg.__columns[i].labelFunction != undefined)
str += "<td width=\""+Math.ceil(dg.__columns[i].width)+"\" "+style+">"+dg.__columns[i].labelFunction(dg.getItemAt(j),dg.__columns[i].columnName)+"</td>";
else
str += "<td width=\""+Math.ceil(dg.__columns[i].width)+"\" "+style+">"+dg.getItemAt(j)[dg.__columns[i].columnName]+"</td>";
}
str += "</tr>";
}
str+="</tbody></table></body></html>";
System.setClipboard(str);
}
function handleOnKeyUp()
{
if(Key.isDown(Key.CONTROL) &&Key.getCode() ==67)
{
mx.managers.CursorManager.setBusyCursor();
doCopy(grid);                    // exchange 'grid' with the id of your datagrid you want copied
mx.managers.CursorManager.removeBusyCursor();
}
}
// only register interest if you want ctrl-c to process a copy of a datagrid. // it's also ctrl + c (on key up, not down)
var obj:Object;
function registerKeyInterest()
{
if(obj == undefined)
{
obj = new Object();
obj.onKeyUp = mx.utils.Delegate.create(this,handleOnKeyUp);
}
Key.addListener(obj);
}
function removeKeyInterest()
{
Key.removeListener(obj);
}
function copyAndOpen(grid)
{
doCopy(grid);
getUrl("javascript:openExcel();");
}
// JAVASCRIPT for your HTML PAGE
<SCRIPT Language="JavaScript1.2">
var excel = null;
function openExcel()
{
try
{
if(excel == null)
{
excel = new ActiveXObject("Excel.Application");
}
var workbook = excel.Workbooks.Add();
workbook.Activate();
var worksheet = workbook.Worksheets("Sheet1");
worksheet.Activate();
worksheet.Paste();
excel.visible=true;
}catch(exception)
{
window.alert("Now you may Paste into an Excel SpreadSheet");
}
}
</SCRIPT>

2. 服务器端导入Excel
2.1 jar包:poi,jxl等。
2.2 使用poi3.7实现的例子。
2.2.1 poi3.7的下载
2.2.2 客户端as:

var variables:URLVariables = new URLVariables();//封装request传输参数
variables.data = 要导出的数据(需要组装成String)
var request:URLRequest = new URLRequest(url); //封装http访问请求  
	request.method = URLRequestMethod.POST;   
	request.data = variables;  
navigateToURL(request,"_self");//返回结果导航到当前窗口的当前帧
2.2.3 Spring配置:
<!-- 控制器映射 -->
	<bean id="outputExcel_urlMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>				
				<prop key="/outputExcel/*.htm">outputExcelController</prop>			
			</props>
		</property>
	</bean>
	
	
	<!-- 静态控制器 -->
  	<bean id="outputExcelStaticController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"     >
		<property name="prefix" value=""/>
  	</bean>
	
	<bean id="outputExcelController" class="com.test.OutputExcelController">
		<property name="methodNameResolver">
			<ref bean="outputExcelControllerResolver" />
		</property>		
	</bean>
	
	<!-- 方法名解析器 -->
	<bean id="outputExcelControllerResolver"
		class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
		<property name="mappings">
			<props>
				<!-- 配置Excel输出URL页面响应 -->	
				<prop key="/outputExcel/outputExcel.htm">doMainDispatch</prop>						 		
			</props>
		</property>
	</bean>

2.2.4 后台Controller,主要完成三个工作一是解析收到的字符串核心是String.split(String regEx),注意为了兼顾正则表达式,有些特殊字符如“$”,“*”,“^”等是不能用于regEx的,最后通过实验,选择了“##”,“:”,“&”作为三级特殊分割字符;二是按照workbook->sheet->row->cell文档结构生成excel文件;最后通过设置HttpServletResponse:: resp.setContentType("application/vnd.ms-excel")直接将生成excel文件写到HttpServletResponse输出流中提供用户下载。参考代码如下:
public void doMainDispatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        logger.info("OutputExcelController:doMainDispatch收到导出Excel请求");      
        resp.reset();
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/vnd.ms-excel");
        String fileName = req.getParameter("fileName");
        resp.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");  
        String[] tokens = {req.getParameter("layerSplitToken"),req.getParameter("headBodySplitToken"),req.getParameter("dataSplitToken")};       
        String head = req.getParameter("head");
        String data = req.getParameter("data");               
        HSSFWorkbook wb = this.generateMultiSheetsExcel(head, data,tokens);//generateExcel(head,data,sheetName);
        wb.write(resp.getOutputStream());        
        resp.getOutputStream().flush();
        resp.getOutputStream().close();
        req.getInputStream().close();
        
    }
    /*
     * @Function:generateMultiSheetsExcel--创建多Sheet的一个Excel文件,其中给个Sheet对应一个图层;
     * @Param:head--每张Sheet名称、列名;
     * @Param:data--每张Sheet的数据;
     * @Param:tokens--分割从请求处获得的head,data字符串所用的特殊字符串
     * @Return:HSSFWorkbook--生成的Excel工作簿;
     */
    private HSSFWorkbook generateMultiSheetsExcel(String head, String data, String[] tokens) {
    	int rowNum=0,colNum=0,totalRowNum = 0;    	
    	HSSFWorkbook hssfworkbook = new HSSFWorkbook (); 
    	HSSFSheet hssfsheet = null; 
    	HSSFRow hssfrow = null;
    	HSSFCell hssfcell = null; 
    	//step1:按”;“分割,获得每张表的head 和 data
    	String strLayerSplitToken = "#";
    	String strHeadDataSplitToken = ":";
    	String strDataSplitToken = "&";
    	if(2 < tokens.length) {
    		strLayerSplitToken = tokens[0];
    		strHeadDataSplitToken = tokens[1];
    		strDataSplitToken = tokens[2];
    	}else if(1< tokens.length && tokens.length <= 2) {
    		strLayerSplitToken = tokens[0];
    		strHeadDataSplitToken = tokens[1];
    	}else if(0 < tokens.length){
    		strLayerSplitToken = tokens[0];
    	} 
    	String[] sheetsArr = head.split(strLayerSplitToken), sheetsDataArr = data.split(strLayerSplitToken);    
    	String[] curSheetArr = null, curSheetDataArr = null;
    	String[] headArr = null, dataArr = null;
    	if(sheetsArr.length == sheetsDataArr.length) {
	    	for(int ii= 0; ii < sheetsArr.length; ++ii) {
	    		//step2:分割图层名与图层字段两部分,获得每张表中表名和字段部分
	    		curSheetArr = sheetsArr[ii].split(strHeadDataSplitToken);
	    		curSheetDataArr = sheetsDataArr[ii].split(strHeadDataSplitToken);
	    		//step2.1:建当前sheet;
	    		hssfsheet = hssfworkbook.createSheet(curSheetArr[0]);    		
	    		//step3:分割图层各字段,为Excel下的每张Sheet中的Cell赋值
	    		if(0 < curSheetArr.length && curSheetArr.length == curSheetDataArr.length) {
	    			headArr = curSheetArr[1].split(strDataSplitToken);
	        		dataArr = curSheetDataArr[1].split(strDataSplitToken);
	        		//step3.1:写入当前Sheet数据;
	        		totalRowNum = dataArr.length/headArr.length;
	        		for(rowNum=0; rowNum<totalRowNum; rowNum++)
	                {
	                	hssfrow = hssfsheet.createRow (rowNum); 
	                	if(0 == rowNum) {
	                		for(colNum=0; colNum < headArr.length; ++colNum) {
	                			hssfcell = hssfrow.createCell ((int) (colNum+1)); 	                			
	                			hssfcell.setCellValue(headArr[colNum]);        			
	                		}
	                	} else {
	                		hssfcell = hssfrow.createCell ((int) 0); //第一列为序号列
                			hssfcell.setCellValue(rowNum);
	                		for(colNum=0; colNum < headArr.length; ++colNum) {
	                			hssfcell = hssfrow.createCell ((int) (colNum+1)); 
	                			hssfcell.setCellValue(dataArr[(rowNum-1)*headArr.length + colNum]);//注意在Excel中第n行为dataArr中的第n-1行数据        			
	                		}
	                	}
	                		
	                }
	    		} else {
	        		logger.error("OutputExcelController:generateMultiSheetsExcel创建Excel失败--head与data两次字段数计算不等");
	        	}
	    		
	    	} 
    	} else {
    		logger.error("OutputExcelController:generateMultiSheetsExcel创建Excel失败--haad与data两次图层数计算不等");
    	}
        return hssfworkbook;
    } 
  
3. 一些参考资料
比较完整的基于poi代码: http://pufan53.iteye.com/blog/903468
poi操作Excel: http://www.codeweblog.com/read-and-write-excel-poi/
比较完整的基于jxls代码: http://java.csecs.com/posts/list/2246.html

你可能感兴趣的:(Flex,Excel)