CSV это формат хранения данных, который используется уже довольно давно. Он представляет собой самый простой способ хранить информацию в виде таблицы и может использоваться в множестве различных приложений.
Эта статья расскажет вам о том, как можно работать с CSV во Flash. Мы вместе напришем класс ActionScript 2.0, который будет обладать всей необходимой функциональностью для использования данных в формате CSV. А затем посмотрим как можно использовать компонент Data Grid для представления данных.
CSV — очень простой формат. Данные хранятся в одном большом string-е, который содержит строки разделенные переносом строки, и столбцы, разделенные запятой(обычно). Благодаря такой незамысловатости он идеален для простых записей, в то время как XML-форматированные записи более сложны.
Другая важная причина, по которой этот формат так популярен, — то, что многие десктопные приложения способны работать с ним. Любая программа, оперирующая электронными таблицами (к примеру, Microsoft Excel), может просматривать, изменять, создавать CSV-файлы. В отличие от XML-форматированных записей, пользователь может просто открыть CSV-файл и легко просмотреть информацию.
Также как XML, CSV — это данные форматированные внутри файла. Он не связан ни с каким специфическим ПО или платформой, и ему не нужно сервера, чтобы быть доставленным клиенту. Это делает CSV и XML очень универсальными способами хранения данных. Вы можете создать flash-приложение основанное на web, а потом без лишних проблем использовать тот же код для постройки CD-ROM-приложения.
CSV не всегда правильное решение для вашего проекта. Благодаря своей гибкости, XMl обычно лучший способ передачи данных клиенту. Следует избегать использования CSV, когда ваши данные не представлены в виде набора строк и столбцов или содержат множественные уровни вложенности. Например, если в одной из ячеек содержится массив или список. XML в этом смысле лучше для разделения разных типов данных и обработки нескольких уровней вложенности. Используйте CSV только для базовых типов данных (String, Number и булевых), которые могут храниться в ячейках таблицы.
Первое, что вы должны знать об этом формате — то, что данные состоят из строк и стобцов. Строки разделяются переносом строки (\n), возвратом каретки (\r) или их комбинацией. Столбцы разделяются обычно запятой (отсюда название - "Comma Separated Values"). Часто первая строка файла используется для задания заголовков столбцов; мы поговорим больше об этом когда будем парсить файл в нашем классе.
Довольно часто в CSV-файлах используется qualifier, в основном двойная кавычка ("). Этот символ используется для точного ограничения значения ячейки. Ниже представлены примеры с ним и без него:
CSV-данные без qualifier-а:
Field 1,Field 2,Field 3,Field 4 Field 5,Field 6,Field 7,Field 8
CSV-данные с qualifier-ом:
"Field 1","Field 2","Field 3","Field 4" "Field 5","Field 6","Field 7","Field 8"
Перед тем, как мы начнем писать наш CSV-класс, нужно уточнить что он должен делать:
Начнем создание класса с его определения. Конструктор оставим пустым, так как он ничего не будет делать.
class CSV {
function CSV() {}
}
Теперь опишем параметры класса:
private var csvData:Array; public var onLoad:Function; public var columns:Array; public var qualifier:String = '';
Первая задача, которая будет выполнятся классом — загрузка данных из файла. Мы реализуем это, создав метод load, который будет получать в качестве своего единственного параметра путь к CSV-файлу. Метод будет использовать класс LoadVars, чтобы загрузить файл, но мы используем неопределенный метод onData в классе LoadVars. Этот метод работает в точности как XML.onData. Он позволит нам получить raw-данные без разбора их классом LoadVars.
public function load(csvPath:String):Void {
var csvLoad:LoadVars = new LoadVars();
csvLoad._parent = this;
csvLoad.onData = function(rawData:String) {
this._parent.onData(rawData);
}
csvLoad.load(csvPath);
}
Заметьте, что в методе LoadVars.onData мы вызываем метод onData нашего класса. onData будет парсить данные после загрузки файла. Как только разбор завершится, данные передадутся назад пользователю через onLoad-метод. Мы не будем в явном виде определять метод onLoad. Юзеры также смогут переопределить метод onData, если они не пожелают парсить данные сразу же.
public function onData(rawData:String):Void {
csvData = parseCSV(rawData);
onLoad();
}
Теперь мы добавим функцию разбора. Сделаем этот метод public для того, чтобы можно было его использовать не только для загружаемых файлов. Парсер -- самая сложная часть этого класса, так как здесь могут возникнуть разные ошибки.
Наш парсер будет получать в качестве единственного параметра сырой csv-текст, а возвращать форматированный массив объектов. Первые две вещи, которые он должен уметь -- определять разделители строк и столбцов. Мы уже знаем, что строки разделяет \r, \n или \r\n. С помощью быстрого поиска мы определим какой из них точно. Разделителем колонок будем считать запятую; как бы то ни было мы можем сделать синтаксический разбор более точным с помощью добавления qualifier-а до и после разделителя.
Сначала разделим исходный csv-текст на массив строк. Это позволит нам пройтись по нему и разобрать каждую строку в отдельности.
Если названия колонок не были определены перед парсингом, мы будем полагать, что первая строка файла содержит названия колонок. Тогда мы будем заполнять массив в соответствии с ними.
Проходя по массиву строк, мы разбиваем каждую на массив ячеек. Если их число не совпадает с числом колонок файла, мы пропускаем эту строку. Перебирая ячейки мы заносим данные в объект, используя в качестве ключа заголовок столбца файла. После этого добавляем этот объект в массив, который будет возвращаться пользователю:
public function parseCSV(rawData:String):Array {
var ii:Number, columnArray:Array, rowObject:Object;
var returnArray:Array = new Array();
var rowDelimiter:String = (rawData.indexOf('\r\n') > -1) ? '\r\n' :
(rawData.indexOf('\r') > -1) ? '\r' : '\n';
var columnDelimiter:String = qualifier + ',' + qualifier;
var rowsArray:Array = rawData.split(rowDelimiter);
if(!columns.length) {
columns = removeQualifier(rowsArray.shift().toString(),
qualifier).split(columnDelimiter);
}
for(var i:Number = 0; i < rowsArray.length; i++) {
columnArray = removeQualifier(rowsArray[i].toString(),
qualifier).split(columnDelim);
if(columnArray.length == columns.length) {
rowObject = new Object();
for(ii = (columnArray.length - 1); ii >= 0; ii--) {
rowObject[columns[ii]] = columnArray[ii];
}
returnArray.push(rowObject);
}
}
return returnArray;
}
Здесь необходимо создать private метод removeQualifier, который будет использоваться парсером. Он будет убирать qualifier с начала и с конца ячейки данных:
private function removeQualifier(originalString:String, qualifier:String):String {
var modifiedString = originalString;
if(modifiedString.charAt(0) == qualifier) {
modifiedString = modifiedString.substring(1);
}
if(modifiedString.charAt(modifiedString.length - 1) == qualifier) {
modifiedString = modifiedString.substring(0, (modifiedString.length - 1));
}
return modifiedString;
}
Чтобы вернуть внутрениий параметр csvData, создадим getter метод data. Его действие будет очень простым -- он будет возвращать распарсенные данные юзеру. Мы делаем это для защиты csvData от записи снаружи класса.
public function get data():Array {
return csvData;
}
В этом примере посмотрим как можно использовать компонент Data Grid для отображения наших CSV-данных. Параметр dataProvider данного компонента принимает массив объектов, как раз как у нас. Первое — нужно поместить инстанцию компонента на stage и указать ей instance name (пусть dataGrid_mc). Затем создайте слой "Actions" и поместите следующий код в его первый фрейм. Убедитесь что файл класса лежит в той же папке, что и FLA-файл.
Первое — создаем экземпляр класса:
var csvLoad:CSV = new CSV();
Затем, задаем столбцы и qualifier:
csvLoad.columns = new Array('Column 1', 'Column 2', 'Column 3');
csvLoad.qualifier = '"';
И последнее — определяем метод onLoad, в котором отдадим данные инстанции компонента Data Grid, а потом начинаем загрузку csv-файла:
csvLoad.onLoad = function() {
dataGrid_mc.dataProvider = this.data;
}
csvLoad.load('sampleData.csv');
Надеюсь эта статья даст вам идеи каким образом можно использовать CSV-данные в вашем Flash-приложении. И, что более важно, я надеюсь она покажет вам конкретный пример построения классов в ActionScript 2.0, удобных для использования и поддержки. Класс CSV может и не быть решением для вашего проекта, однако приведенные принципы объектно-ориентированного программирования следует стараться использовать практически в каждом вашем Flash-приложении.
В прикрепленном архиве находится пример полного кода, разобранного в статье.
Оригинал CSV in Flash MX 2004
Перевод 3hrek
| Прикрепленный файл | Размер |
|---|---|
| csv-actionscript.rar | 89.64 кб |
Комментарии
Не отображаются русские символы (((
Корректно работает только с латиницей
Отправить комментарий