您的位置:首页 > 编程语言 > Java开发

Flex通过Java读取Excel(详细流程)----Excel在客户端(DataGrid动态根据Excel生成)

2011-08-10 13:19 549 查看
2011-03-06 23:57:00| 分类:

flex/flash | 标签:excel flex java 客户端 as3xls
|字号大中小 订阅

在网上查了很久的资料,就是想要把客户端的Excel直接在flex的datagrid中显示。网上的资料只有将datagrid的数据通过as3xls保存到本地。以及在AIR运用中通过as3xls读取本地的Excel文件。还有一点是,通过as3xls保存在本地Excel文档无法再被as3xls或POI(即马上要介绍的两种方法)打开。

本人通过不断尝试,终于有了结果:

方法一:

模仿AIR中采用as3xls读取客户端的Excel文件,再将其绑定到DataGrid控件中。相关的AIR中as3xls读取Excel文件的文献很多,这里只说一下思想。采用FileReference代替AIR中的File,并通过FileReference的load事件得到ByteArray,从而初始化as3xls变量。

这种方法的优点在于:所有事件都是在客户端上完成,不耗费服务器的资源。但致命的缺点在于读取的数据存在中文乱码问题。

并且as3xls是2008年出的,一直没有更新。另外,网上所说的解决中文乱码的as3xls,是指解决的写入Excel的中文乱码,而读取的未解决。所以不推荐!!!

方法二:

思想:方法一中可以得到Excel的ByteArray,这里将其通过Blaseds传到java服务器端。并通过ByteArrayInputStream将byte[] (ByteArray在java中的映射)转化为InputStream,再转化为POIFSFileSystem,最后至HSSFWorkbook。然后与Flex通过Java读取Excel(详细流程)----Excel在服务器端一样,将处理完的数据传回flex端(所有的转化只需通过构造函数即可)。

先介绍工具和方法

1.Java通过第三方控件POI操作Excel,请参考POI读取Excel(简单程序)POI3.7下载

2.Blazeds连接flex4和java,请参考flex4+blazeds+java通信(视频)

代码部分:

java:

import java.io.ByteArrayInputStream;

import java.io.FileInputStream;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.HashMap;

import org.apache.poi.hssf.usermodel.HSSFCell;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;

import org.apache.poi.hssf.usermodel.HSSFRow;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import org.apache.poi.ss.usermodel.Cell;

import flex.messaging.io.ArrayCollection;

public class ReadExcel {

public ArrayCollection readfromflex(byte[] file) {

ArrayCollection arrc = new ArrayCollection();

try {

InputStream is = new ByteArrayInputStream(file);

POIFSFileSystem fs = new POIFSFileSystem(is);

HSSFWorkbook workBook = new HSSFWorkbook(fs);

System.out.println("工作表个数 :" + workBook.getNumberOfSheets()

+ "<br>");

for (int i = 0; i < workBook.getNumberOfSheets(); i++) {

System.out.println("<font color='red'> " + i

+ " ***************工作表名称:" + workBook.getSheetName(i)

+ " ************</font><br>");

// 创建工作表

HSSFSheet sheet = workBook.getSheetAt(i);

int rows = sheet.getPhysicalNumberOfRows(); // 获得行数

if (rows > 0) {

sheet.getMargin(HSSFSheet.TopMargin);

for (int j = 0; j < rows; j++) { // 行循环

HSSFRow row = sheet.getRow(j);

if (row != null) {

int cells = row.getLastCellNum();// 获得列数

HashMap<String, String> hashmap= new HashMap<String, String>();

for (int k = 0; k < cells; k++) { // 列循环

HSSFCell cell = row.getCell(k); // /////////////////////

if (cell != null) {

String value = "";

value = readcell(cell);

hashmap.put("col"+k, value);

}

}

arrc.add(hashmap);

}

}

}

}

} catch (Exception ex) {

ex.printStackTrace();

}

return arrc;

}

public String readcell(HSSFCell cell) {

String value = "";

switch (cell.getCellType()) {

case HSSFCell.CELL_TYPE_NUMERIC: // 数值型

if (HSSFDateUtil.isCellDateFormatted(cell)) {

// 如果是date类型则 ,获取该cell的date值

Date date = new Date() ;

date = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());

SimpleDateFormat SDF=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");

value = SDF.format(date) ;

} else {// 纯数字

cell.setCellType (Cell.CELL_TYPE_STRING);

value = cell.getRichStringCellValue().toString();

//value = String.valueOf(cell.getNumericCellValue());//这会出现1.0 2.0的情况

}

break;

//此行表示单元格的内容为string类型

case HSSFCell.CELL_TYPE_STRING: // 字符串型

value = cell.getRichStringCellValue().toString();

break;

case HSSFCell.CELL_TYPE_FORMULA:// 公式型

// 读公式计算值

value = String.valueOf(cell.getNumericCellValue());

if (value.equals("NaN")) {// 如果获取的数据值为非法值,则转换为获取字符串

value = cell.getRichStringCellValue().toString();

}

// cell.getCellFormula();读公式

break;

case HSSFCell.CELL_TYPE_BOOLEAN:// 布尔

value = " " + cell.getBooleanCellValue();

break;

//此行表示该单元格值为空

case HSSFCell.CELL_TYPE_BLANK: // 空值

value = "";

break;

case HSSFCell.CELL_TYPE_ERROR: // 故障

value = "";

break;

default:

value = cell.getRichStringCellValue().toString();

}

return value;

}

}

2.flex(mxml)部分

<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:s="library://ns.adobe.com/flex/spark"

xmlns:mx="library://ns.adobe.com/flex/mx"

width="100%" height="100%" xmlns:services="services.*">

<fx:Declarations>

<s:CallResponder id="readfromflexResult"/>

<services:Read id="read" result="readok()" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>

<!-- 将非可视元素(例如服务、值对象)放在此处 -->

</fx:Declarations>

<fx:Script>

<![CDATA[

import flash.net.FileReference;

import mx.collections.ArrayCollection;

import mx.controls.Alert;

import mx.controls.dataGridClasses.DataGridColumn;

private var fr:FileReference=new FileReference();

[Bindable]

public var datap:ArrayCollection;

protected function button1_clickHandler(event:MouseEvent):void

{

var modeltype:FileFilter = new FileFilter("Excel文件(*.xls)", "*.xls");

var FileTypes:Array = new Array(modeltype);

fr.addEventListener(Event.SELECT, fileRef_event);

fr.addEventListener(ProgressEvent.PROGRESS, fileRef_event);

//fr.addEventListener(Event.COMPLETE, fileRef_event);

fr.browse(FileTypes);

}

public function fileRef_event(evt:Event):void{

switch(evt.type)

{

case Event.SELECT:

fr.load();

fr.addEventListener(Event.COMPLETE,fileLoaded);

break;

case ProgressEvent.PROGRESS:

//label_updatastate.text="上传中...";

//Math.round(100 * (ProgressEvent)evt.bytesLoaded / (ProgressEvent)evt.bytesTotal);

break;

case Event.COMPLETE:

//label_updatastate.text="上传完成!";

break;

case IOErrorEvent.IO_ERROR:

//label_updatastate.text="上传失败!";

break;

}

}

public function fileLoaded(evt:Event):void{

switch(evt.type)

{

case Event.COMPLETE:

readfromflex(evt.target.data);

break;

case IOErrorEvent.IO_ERROR:

break;

}

}

protected function readok():void

{

var xlsdata:ArrayCollection=readfromflexResult.lastResult;

var xlshead:Object=xlsdata.removeItemAt(0);//这之前最好对xlsdata的长度进行验证,防止读到的是空Excel表,我忘了验证。

var arr:Array = new Array();

for(var attribute:String in xlshead)//开始动态创建DataGrid

{

var dgc:DataGridColumn=new DataGridColumn();

dgc.headerText=xlshead[attribute];

dgc.dataField=attribute;

arr.push(dgc);

}

datap=xlsdata;

datagrid.columns=arr.sortOn("dataField",Array.CASEINSENSITIVE);//对数据排序一下,保证和Excel中的位置一致。

}

protected function readfromflex(arg0:ByteArray):void

{

readfromflexResult.token = read.readfromflex(arg0);

}

]]>

</fx:Script>

<s:VGroup>

<mx:DataGrid x="100" y="100" id="datagrid" dataProvider="{datap}">

<!--<mx:columns>

<mx:DataGridColumn headerText="列 1" dataField="col1"/>

</mx:columns>-->

</mx:DataGrid>

<s:Button label="读取" fontSize="13" click="button1_clickHandler(event)"/>

</s:VGroup>

</s:Application>

中间blazeds的xml配置部分已省略,请自己参考视频配置。

来自:http://zhangyuefeng1983.blog.163.com/blog/static/1083372520112611193020/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: