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

47 篇文章 0 订阅
  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配置部分已省略,请自己参考视频配置。

 
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:Script> <![CDATA[ import mx.controls.CheckBox; import mx.controls.Alert; import com.as3xls.xls.ExcelFile; import com.as3xls.xls.Sheet; import flash.filesystem.*; [Bindable] private var dp:Array = [ {idx:1, names: "test1", sex: "b" }, {idx:2, names: "test2", sex: "g" } ]; public function doSelect(o:Object):void { Alert.show("行的数据分别是:"+o.idx+"/"+o.names+"/"+o.sex); } private var sheet:Sheet; private function onCreate():void { var excelFile:ExcelFile = new ExcelFile(); sheet = new Sheet(); sheet.resize(10, 10); sheet.setCell(0, 0, "Today's date:"); sheet.setCell(0, 1, new Date()); excelFile.sheets.addItem(sheet); var mbytes:ByteArray = excelFile.saveToByteArray(); var stream:FileStream = new FileStream(); var docsDir:File = File.documentsDirectory.resolvePath("abc.xls"); // 定死文件名 try { docsDir.browseForSave("Save As"); docsDir.addEventListener(Event.SELECT, saveData); } catch (error:Error) { trace("Failed:", error.message) } function saveData(event:Event):void { var newFile:File = event.target as File; if (!newFile.exists) { var stream:FileStream = new FileStream(); stream.open(newFile, FileMode.WRITE); stream.writeBytes(mbytes); // 写文件流 stream.close(); } } } ]]> </mx:Script> <mx:Panel> <mx:Button label="导出" click="onCreate()"/> <mx:DataGrid id="dg1" dataProvider ="{dp}"> <mx:columns> <mx:DataGridColumn width="20" headerText="" > <mx:itemRenderer> <mx:Component> <mx:CheckBox change=" {outerDocument.doSelect(data as Object)} " /> </mx:Component> </mx:itemRenderer> </mx:DataGridColumn> <mx:DataGridColumn headerText="names" dataField="names" width="200" /> <mx:DataGridColumn headerText="sex" dataField="sex" width="300" /> </mx:columns> </mx:DataGrid> </mx:Panel> </mx:WindowedApplication>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

帆软爱好者

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值