root/as3/CSVUtils/src/com/kujirahand/CSVUtils.as

リビジョン 836, 9.6 kB (コミッタ: kujirahand, コミット時期: 6 ヶ月 前)

コメントを少し修正

Line 
1 /**
2  *  Excel 準拠の CSV ファイルを配列変数に変換するクラス
3  */
4
5 package com.kujirahand
6 {
7     import mx.collections.ArrayCollection;
8    
9     /**
10      * CSV ファイル(Excel準拠)のテキストを、Array や ArrayCollection に変換するもの。
11      * @author クジラ飛行机(http://kujirahand.com)
12      * @langversion ActionScript 3.0
13      * @example CSV形式のテキストを配列に変換する
14      * <listing version="3.0" >
15      *    var csv_str = "name, value\naaa,30\nbbbb,50\ncccc,30\n";
16      *    var csv_ary:Array = CSVUtils.CsvToArray(csv_str); // CSV→Array
17      *    trace( CSVUtils.ArrayToCsv(csv_ary) ); // Array→CSV
18      * </listing>
19      * @example DataGrid に CSVテキストを表示する
20      * <listing version="3.0" >
21      *    // &lt;mx:DataGrid id="data_grid"&gt;
22      *    //    &lt;mx:DataGridColumn dataField="name"/&gt;
23      *    //    &lt;mx:DataGridColumn dataField="tel"/&gt;
24      *    //    &lt;mx:DataGridColumn dataField="memo"/&gt;
25      *    // &lt;/mx:DataGrid&gt;
26      *    var csv_str = "name, tel, memo\naaa,03-xxx-xxxx,memo\nbbbb,03-xxx-xxxx\n";
27      *    var csv_ary:Array = CSVUtils.CsvToArray(csv_str); // CSV→Array
28      *    var mapping:Array = ['name', 'tel', 'memo'];
29      *    var csv_ac:ArrayCollection;
30      *    csv_ac = CSVUtils.ArrayToArrayCollection(csv_ary, mapping, true);
31      *    data_grid.dataProvider = csv_ac; // set to DataGrid
32      * </listing>
33      * @see http://www.libspark.org/wiki/kujirahand/CSVUtils WIKI
34      * @see http://www.libspark.org/browser/as3/CSVUtils/src/com/kujirahand/CSVUtils.as 最新版ダウンロード(SVNリポジトリ)
35      * @see http://kujirahand.com/as3/com/kujirahand/CSVUtils.html ASDoc
36      */
37     public class CSVUtils
38     {
39         // 静的メソッド
40         /** CSV の列の区切り記号(1文字のみ対応) */ 
41         public static var DEFAULT_SPLITTER:String = ",";
42         /** 行の区切り記号は \n で固定 */
43         public static const LINE_SPLLITER:String = "\n";
44        
45         /** CSV を配列に変換する関数
46          * @param csv_str   CSV文字列
47          * @return   二次元配列変数
48          */
49         public static function CsvToArray(csv_str:String):Array {
50             return CsvToArray_spl(csv_str, DEFAULT_SPLITTER);
51         }
52        
53         /**
54          * TSVを配列に変換する関数
55          * @param tsv_str    TSV文字列
56          * @return         二次元配列変数
57          */
58         public static function TsvToArray(tsv_str:String):Array {
59             return CsvToArray_spl(tsv_str, "\t");
60         }
61        
62         /** 任意の区切り記号のCSVを配列に変換する関数 */
63         public static function CsvToArray_spl(csv_str:String, splitter:String):Array {
64             var csv:CSVUtils = new CSVUtils();
65             return csv.split(csv_str, splitter);
66         }
67        
68         public static function replaceStr(str:String, a:String, b:String):String {
69             var o:Array = str.split(a);
70             return o.join(b);
71         }
72         /**
73         * CSVファイルをデータグリッドに表示するために、ArrayCollectionに変換する
74         * @param    csv_ary    二次元配列変数
75         * @param    mapping     マッピングするフィールド名の配列
76         * @param    topline_is_header 1行目をヘッダとして利用しているなら true にすると削る
77         * @return    変換された ArrayCollection
78         */
79         public static function ArrayToArrayCollection(csv_ary:Array,
80             mapping:Array, topline_is_header:Boolean = false):ArrayCollection {
81             if (topline_is_header) { // 1行目をヘッダとして使うなら削る
82                 csv_ary.splice(0, 1);
83             }
84             var result_ary:ArrayCollection = new ArrayCollection();
85             for (var row:int = 0; row < csv_ary.length; row++) {
86                 var cols:Array = csv_ary[row];
87                 var col_obj:Object = {};
88                 for (var col:int = 0; col < mapping.length; col++) {
89                     var field_name:String = mapping[col];
90                     var col_str:String = cols[col];
91                     if (field_name == ""||field_name == null) continue;
92                     col_obj[field_name] = col_str;
93                 }
94                 result_ary.addItem(col_obj);
95             }
96             return result_ary;
97         }
98         /**
99         * 二次元配列をCSV形式に変換する
100         * @param csv_ary        配列変数
101         * @param splitter        区切り記号
102         * @param use_escape    必ず ダブルコーテーションで囲う場合
103         * @return CSV形式の文字列
104         */
105         public static function ArrayToCsv(csv_ary:Array, splitter:String,
106             use_escape:Boolean = false):String {
107             var res:String = "";
108             for (var row:int = 0; row < csv_ary.length; row++) {
109                 var cols:Array = csv_ary[row];
110                 for (var col:int = 0; col <  cols.length; col++) {
111                     var cell:String = cols[col];
112                     if (use_escape || hasEscapeChar(cell, splitter)) {
113                         cell = escapeCell(cell);
114                     }
115                     res += cell + splitter;
116                 }
117                 if (cols.length > 0) res = res.substr(0, res.length -1);
118                 res += LINE_SPLLITER;
119             }
120             if (csv_ary.length > 0) res = res.substr(0, res.length - 1);
121             return res;
122         }
123         /**
124         * 文字列を ".." で括る必要があるかチェックする
125         */
126         public static function hasEscapeChar(cell:String, splitter:String):Boolean {
127             if (cell.indexOf('"') >= 0) return true;
128             if (cell.indexOf("\n") >= 0) return true;
129             if (cell.indexOf("\r") >= 0) return true;
130             if (cell.indexOf("\t") >= 0) return true;
131             if (cell.indexOf(" ") >= 0) return true;
132             if (cell.indexOf(splitter) >= 0) return true;
133             return false;
134         }
135         /**
136         * CSVのセル(文字列)を ".." で括ってエスケープする
137         */
138         public static function escapeCell(cell:String):String {
139             cell = replaceStr(cell, '"', '""');
140             cell = '"' + cell + '"';
141             return cell;
142         }
143         // ------------------
144         // CSVUtils クラス
145         private var csv_str:String;
146         private var splitter:String;
147         private var index:int;
148        
149         public function split(csv_str:String, splitter:String):Array {
150             // 改行を統一する
151             csv_str = replaceStr(csv_str, "\r\n", LINE_SPLLITER);
152             csv_str = replaceStr(csv_str, "\r", LINE_SPLLITER);
153             //
154             this.csv_str = csv_str;
155             this.splitter = splitter;
156             //
157             return splitLoop();
158         }
159         private function splitLoop():Array {
160             var result:Array = [];
161             while (csv_str.length > 0) {
162                 var cols:Array = getCols();
163                 result.push(cols);
164             }
165             return result;
166         }
167         private function getCols():Array {
168             var cols:Array = [];
169             index = 0;
170             while (index < csv_str.length) {
171                 var c:String = csv_str.charAt(index);
172                 var col:String;
173                 if (c == LINE_SPLLITER) {
174                     index++;
175                     break;
176                 }
177                 if (c == '"') {
178                     col = getColStr();
179                 }
180                 else {
181                     col = getColSimple(); 
182                 }
183                 skipSpace();
184                 cols.push(col);
185             }
186             // 切り取る
187             csv_str = csv_str.substr(index);
188             return cols;
189         }
190         private function getColSimple():String {
191             var col:String = "";
192             while (index < csv_str.length) {
193                 if (csv_str.substr(index, 2) == '""') {
194                     col += '"';
195                     index += 2;
196                     continue;
197                 }
198                 var c:String = csv_str.charAt(index);
199                 if (c == splitter) {
200                     index++;
201                     break;
202                 }
203                 if (c == LINE_SPLLITER) {
204                     break;
205                 }
206                 col += c;
207                 index++;               
208             }
209             return col;
210         }
211         private function getColStr():String {
212             // "str" の文字列
213             index++; // skip '"'
214             var col:String = "";
215             while (index < csv_str.length) {
216                 if (csv_str.substr(index, 2) == '""') {
217                     col += '"';
218                     index += 2;
219                     continue;
220                 }
221                 var c:String = csv_str.charAt(index);
222                 if (c == '"') { // 終端 '"' の可能性
223                     index++;
224                     skipSpace();
225                     // 終端のはず、もし違えば、壊れた形式の可能性があるが継続する
226                     if (csv_str.charAt(index) == ",") {
227                         index++;
228                     }
229                     break;
230                 }
231                 col += c;
232                 index++;               
233             }
234             return col;
235         }
236         private function skipSpace():void {
237             if (csv_str.charAt(index) == " ") {
238                 index++;
239             }
240         }
241     }
242 }
243
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。