<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IT妖怪 &#187; AIR</title>
	<atom:link href="http://blog.ityao.com/archives/tag/air/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.ityao.com</link>
	<description>热爱生活，热爱程序</description>
	<lastBuildDate>Wed, 03 Aug 2011 02:56:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Parsley AIR发布问题解决方法</title>
		<link>http://blog.ityao.com/archives/731</link>
		<comments>http://blog.ityao.com/archives/731#comments</comments>
		<pubDate>Sat, 05 Jun 2010 03:51:30 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[ADOBE RIA]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[parsley]]></category>

		<guid isPermaLink="false">http://blog.ityao.com/?p=731</guid>
		<description><![CDATA[之前在项目中使用Parsley做为框架，在把依赖的swc用RSL进行发布AIR的情况下，会Inject不了， 后来发现是AIR在IDE里面进行release发布的时候应该是没有把相关的metadata实现编译进去，于是就查了一下，发现不使用IDE的重新编译，使用命令行手工打包可以解决这个问题， 命令行如下：]]></description>
			<content:encoded><![CDATA[<p>之前在项目中使用Parsley做为框架，在把依赖的swc用RSL进行发布AIR的情况下，会Inject不了，<br />
后来发现是AIR在IDE里面进行release发布的时候应该是没有把相关的metadata实现编译进去，于是就查了一下，发现不使用IDE的重新编译，使用命令行手工打包可以解决这个问题，<br />
命令行如下：</p>
<pre class="brush: plain; title: ; notranslate">
adt -package -storetype pkcs12 -keystore certificat e.p12 -storepass 123456 TestAirMetadata.air bin-debug/TestAirMetadata-app.xml -C bin-debug .
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.ityao.com/archives/731/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flex User Group文档&#8211;AIR介绍</title>
		<link>http://blog.ityao.com/archives/706</link>
		<comments>http://blog.ityao.com/archives/706#comments</comments>
		<pubDate>Thu, 27 May 2010 02:18:44 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[ADOBE RIA]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[doc]]></category>

		<guid isPermaLink="false">http://blog.ityao.com/?p=706</guid>
		<description><![CDATA[一个很有用的PPT,用于向不了解这技术的人介绍 点击下载]]></description>
			<content:encoded><![CDATA[<p>一个很有用的PPT,用于向不了解这技术的人介绍<br />
<a href="http://www.ityao.com/tool/ityao.com_introToAIR_community.rar">点击下载</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ityao.com/archives/706/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AIR读取CSV文件并进行保存</title>
		<link>http://blog.ityao.com/archives/198</link>
		<comments>http://blog.ityao.com/archives/198#comments</comments>
		<pubDate>Fri, 11 Sep 2009 02:41:28 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Adobe Flex]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[pimento]]></category>

		<guid isPermaLink="false">http://blog.cnflex.org/?p=198</guid>
		<description><![CDATA[最近在帮一个朋友做一个程序，其中用到AIR读取Excel导出的CSV文件进行数据导入数据库的工作，中间碰到了一些问题，最后都可以一一解决，感觉挺有意思，特意拿来个大家分享一下。 完整代码在本贴的最后，完成的效果如下图所示： 具体开发步骤如下 第一步，CSV文件格式设置和导出： 通常一些业务资料会保存在Excel当中，CSV可以通过Excel文件的&#8221;另存为&#8221;获得这个格式的文件，不过要注意的是CSV的分隔符在某些机器上是&#8221;,&#8221;某些是&#8221;;&#8221;，这个是通过控制面板（&#8221;日期，时间语言和区域设置&#8221;->&#8221;区域和语言选项&#8221;->&#8221;自定义&#8221;->&#8221;列表分隔符&#8221; ）进行设置的。我的操作系统是XP，用的是Excel 2007，导出的时候是&#8221;;&#8221;。 可能在别的系统下操作会有所不同，在我的机器上导出的CSV文件是ansi内码。 第二步，获得文件的引用： 这里使用了两种不同的方式去获得文件的引用（即选择文件），一种是点击一个按钮，另一种是直接把csv文件拖动到界面上。 点击按钮选择文件更直观写，这部分代码如下： 这里设置了类型过滤器，用户只能选择&#8221;csv&#8221;结尾的文件，方便在一大堆文件中找出这个文件。 选择具体的文件后就可以读取里面的数据了。 而另外一种方法是把要读取的文件进程序中以完成数据导入，这种方式更直观快捷。 第三步，判断文件编码，然后读取文件： 之前刚完成程序后进行测试，csv文件里面有大量的中文内容，一开始没判断代码的时候直接使用下面的语句读取文件： 后来更发现数据进数据库后会是乱码，才知道这个csv文件不是UTF8的格式，是ANSI的，用notepad另存编码为UTF8就可以正常导入数据了。 追查原因，是因为这个ansi文件是不能正确用UTF的方式去读的。 那么以后怎么自动识别文件内码并正确读取而不变成乱码呢，于是就上搜索引擎搜索，终于找到一篇文章，抄了上面一段自动判断文件编码的代码。一句话概括之&#8211;先判断内容编码格式再按照编码格式去读取其数据就没错了！ 第四步，导入CSV的数据到数据库中： 这一步相对简单，首先是删除数据库已有的数据，然后把上一步中读成字符串的文件内容每行解析成一条数据，然后导入数据库中，这里使用了pimento框架的持久层实现方法，可以很容易地在Actionscript端完成CRUD的操作，代码如下： 删除已有数据,和服务器端JAVA EE里JPA的实现代码几乎一样： 然后是拆分CSV的文件，并把记录导入数据库 是不是觉得很有趣呢，在一个flex页面中就完成了一个独立的功能的前后台实现了，希望这个帖子能引起大家对parsley和pimento这两个框架的兴趣，过段时间我会继续写一些相关的介绍。 完整的程序代码如下：]]></description>
			<content:encoded><![CDATA[<p>最近在帮一个朋友做一个程序，其中用到AIR读取Excel导出的CSV文件进行数据导入数据库的工作，中间碰到了一些问题，最后都可以一一解决，感觉挺有意思，特意拿来个大家分享一下。<br />
<span id="more-198"></span><br />
完整代码在本贴的最后，完成的效果如下图所示：<br />
<img src="http://blog.cnflex.org/wp-content/uploads/2009/09/csvdrop.jpg" alt="csvdrop" title="csvdrop" width="500" height="379" class="alignnone size-full wp-image-205" /></p>
<p><strong>具体开发步骤如下</strong></p>
<ul>
<li><strong>第一步，CSV文件格式设置和导出：</strong><br />
通常一些业务资料会保存在Excel当中，CSV可以通过Excel文件的&#8221;另存为&#8221;获得这个格式的文件，不过要注意的是CSV的分隔符在某些机器上是&#8221;,&#8221;某些是&#8221;;&#8221;，这个是通过控制面板（&#8221;日期，时间语言和区域设置&#8221;->&#8221;区域和语言选项&#8221;->&#8221;自定义&#8221;->&#8221;列表分隔符&#8221; ）进行设置的。我的操作系统是XP，用的是Excel 2007，导出的时候是&#8221;;&#8221;。<br />
可能在别的系统下操作会有所不同，在我的机器上导出的CSV文件是ansi内码。
</li>
<li><strong>第二步，获得文件的引用：</strong><br />
这里使用了两种不同的方式去获得文件的引用（即选择文件），一种是点击一个按钮，另一种是直接把csv文件拖动到界面上。<br />
点击按钮选择文件更直观写，这部分代码如下：</p>
<pre class="brush: xml; title: ; notranslate">
private function browseFile():void{
	var typeFilters:Array = new Array();
	var typeFilter:FileFilter;
	typeFilter = new FileFilter(&quot;CSV Files(*.csv)&quot;, &quot;*.csv&quot;);
	typeFilters.push(typeFilter);

        var file:File = new File();
        file.addEventListener(Event.SELECT, importData);
        file.browseForOpen(&quot;选择要导入的CSV数据文件&quot;,typeFilters);
}
</pre>
<p>这里设置了类型过滤器，用户只能选择&#8221;csv&#8221;结尾的文件，方便在一大堆文件中找出这个文件。</p>
<pre class="brush: as3; title: ; notranslate">
private function importData(e:Event):void{
     var file:File = new File(e.target.nativePath);
     getFileContent(file);
        	}
</pre>
<p>选择具体的文件后就可以读取里面的数据了。</p>
<p>而另外一种方法是把要读取的文件进程序中以完成数据导入，这种方式更直观快捷。
</li>
<li><strong>第三步，判断文件编码，然后读取文件：</strong><br />
之前刚完成程序后进行测试，csv文件里面有大量的中文内容，一开始没判断代码的时候直接使用下面的语句读取文件：</p>
<pre class="brush: as3; title: ; notranslate">var fileContent:String = fileStream.readUTFBytes(fileStream.bytesAvailable)</pre>
<p>后来更发现数据进数据库后会是乱码，才知道这个csv文件不是UTF8的格式，是ANSI的，用notepad另存编码为UTF8就可以正常导入数据了。<br />
追查原因，是因为这个ansi文件是不能正确用UTF的方式去读的。<br />
那么以后怎么自动识别文件内码并正确读取而不变成乱码呢，于是就上搜索引擎搜索，终于找到一篇<a href="http://l4cd.net/Blog/article.asp?id=125">文章</a>，抄了上面一段自动判断文件编码的代码。一句话概括之&#8211;先判断内容编码格式再按照编码格式去读取其数据就没错了！</p>
<pre class="brush: as3; title: ; notranslate">
var code:String;
switch(true){
     case (b1==-1&amp;&amp;b2==-2):
          code = &quot;unicode&quot;;
          break;
    case (b1==-2&amp;&amp;b2==-1):
     	  code = &quot;unicodeFFFE&quot;;
	  break;
    case (b1==-17&amp;&amp;b2==-69):
    	   code = &quot;utf-8&quot;;
	   break;
    default:	code = &quot;ansi&quot;;
break;
}
var fileContent:String = fileStream.readMultiByte(fileStream.bytesAvailable,code);
fileStream.close();
</pre>
</li>
<li><strong>第四步，导入CSV的数据到数据库中：</strong><br />
这一步相对简单，首先是删除数据库已有的数据，然后把上一步中读成字符串的文件内容每行解析成一条数据，然后导入数据库中，这里使用了<a href="http://www.spicefactory.org/pimento/">pimento</a>框架的持久层实现方法，可以很容易地在Actionscript端完成CRUD的操作，代码如下：</p>
<p>删除已有数据,和服务器端JAVA EE里JPA的实现代码几乎一样：</p>
<pre class="brush: as3; title: ; notranslate">
private function parseCSV():void{
	var query:Query = entityManager.createQuery(&quot;DELETE FROM Owner o WHERE o.orgID=:orgID&quot;);
	query.setNamedParameter(&quot;orgID&quot;,curOrg.id);
	query.executeUpdate().addResultHandler(successDeleteOwner);
	if(owners!=null &amp;&amp; owners.length&gt;0){
		owners.removeAll();
	}else if(owners==null){
		owners = new ArrayCollection();
	}
}
</pre>
<p>然后是拆分CSV的文件，并把记录导入数据库</p>
<pre class="brush: as3; title: ; notranslate">
private function successDeleteOwner(rows:int):void{
	var csvArray:Array = new Array();
	var csvLines:Array = _content.split(String.fromCharCode(13,10));
	csvLines.splice(0,1);
	for each(var s:String in csvLines){
		var lineItems:Array = s.split(&quot;,&quot;);
		var owner:Owner = new Owner();
		owner.homeNumber = lineItems[3];
		owner.orgID = curOrg.id;
		owner.ownerName = lineItems[1];
		owner.propertyID =  lineItems[0];
		owner.smsNumber = lineItems[2];
		owner.remark = lineItems[4];
		entityManager.persist(owner).addResultHandler(successCreatedOwner);
	}
}
</pre>
</li>
</ul>
<p><br/><br />
是不是觉得很有趣呢，在一个flex页面中就完成了一个独立的功能的前后台实现了，希望这个帖子能引起大家对parsley和pimento这两个框架的兴趣，过段时间我会继续写一些相关的介绍。</p>
<p><br/></p>
<hr/>
完整的程序代码如下：</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:VBox xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
	addedToStage=&quot;dispatchEvent(new Event('configureIOC', true))&quot; horizontalAlign=&quot;center&quot;
	width=&quot;100%&quot; height=&quot;100%&quot; creationComplete=&quot;listOrginazation()&quot;
	horizontalScrollPolicy=&quot;off&quot; verticalScrollPolicy=&quot;off&quot;
	nativeDragEnter=&quot;dragEnterHandler(event)&quot; nativeDragDrop=&quot;dragDropHandler(event)&quot;&gt;

	&lt;mx:Script&gt;
		&lt;![CDATA[
			import flash.utils.setTimeout;
			import org.spicefactory.lib.reflect.types.Void;
			import mx.events.ListEvent;
			import mx.events.ItemClickEvent;
			import org.spicefactory.pimento.service.Query;
			import mx.collections.ArrayCollection;
			import org.spicefactory.cinnamon.service.ErrorMessage;
			import mx.controls.Alert;
			import mx.utils.StringUtil;
			import com.coralbay.model.Organization;
			import com.coralbay.model.Owner;
			import org.spicefactory.pimento.service.EntityManager;

			[Inject]
			public var entityManager:EntityManager;

			[Bindable]
			private var organizations:ArrayCollection;

			[Bindable]
			private var curOrg:Organization = null;

			[Bindable]
			private var curOwner:Owner = null;			

			[Bindable]
			private var owners:ArrayCollection;

			private function listOrginazation():void{
				var query:Query = entityManager.createQuery(&quot;select o from Organization o Order By o.createTime desc&quot;);
				query.getResultList().addResultHandler(onResult);
			}

			private function onResult (orgs:Array) : void {
			    organizations = new ArrayCollection(orgs);
			    if(orgs.length&gt;0){
			    	curOrg = orgs[0];
			    	orgList.selectedIndex = 0;
			    }else{
			    	curOrg = null;
			    }
			}

			private function changeOrg():void{
				curOrg = orgList.selectedItem as Organization;
				listowner(curOrg.id);
			}

			private function listowner(orgId:int):void{
				var query:Query = entityManager.createQuery(&quot;select o from Owner o WHERE o.orgID=:orgID&quot;);
			    	query.setNamedParameter(&quot;orgID&quot;,orgId);
			    	query.getResultList().addResultHandler(onownerResult);
			}

			private function onownerResult(ops:Array):void{
				owners = new ArrayCollection(ops);
			}

			private function browseFile():void{  

				var typeFilters:Array = new Array();
				var typeFilter:FileFilter;
				typeFilter = new FileFilter(&quot;CSV Files(*.csv)&quot;, &quot;*.csv&quot;);
				typeFilters.push(typeFilter);

            	var file:File = new File();
            	file.addEventListener(Event.SELECT, importData);
            	file.browseForOpen(&quot;选择要导入的CSV数据文件&quot;,typeFilters);
        	}  

        	private function importData(e:Event):void{
            	//Alert.show(e.target.nativePath);
            	var file:File = new File(e.target.nativePath);
            	getFileContent(file);
        	}  

			private function dragEnterHandler(evt:NativeDragEvent):void{

				if(evt.clipboard.hasFormat(ClipboardFormats.FILE_LIST_FORMAT)){
					var dropFiles:Array = evt.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
					if(dropFiles.length&gt;1){
						Alert.show(&quot;只能选择一份CSV文件&quot;);
						return;
					}
					var file:File = dropFiles[0] as File;
					if(file.extension == &quot;csv&quot;){
						NativeDragManager.acceptDragDrop(this);
					}
				}
			} 

			private function dragDropHandler(evt:NativeDragEvent):void{
				//Alert.show(&quot;hihi&quot;);
				NativeDragManager.dropAction = NativeDragActions.COPY;
				var dropFiles:Array = evt.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
				getFileContent(dropFiles[0]);
			} 

			private var _content:String;
			private function getFileContent(_file:File):void{

				var fileStream:FileStream = new FileStream();
				fileStream.open(_file, FileMode.READ);
				var b1:int = fileStream.readByte();
				var b2:int = fileStream.readByte();
				fileStream.position = 0;
				var code:String;
				switch(true)
				{
					case (b1==-1&amp;&amp;b2==-2):
						code = &quot;unicode&quot;;
						break;
					case (b1==-2&amp;&amp;b2==-1):
						code = &quot;unicodeFFFE&quot;;
						break;
					case (b1==-17&amp;&amp;b2==-69):
						code = &quot;utf-8&quot;;
						break;
					default:
						code = &quot;ansi&quot;;
						break;
				}
				//var fileContent:String = fileStream.readUTFBytes(fileStream.bytesAvailable);
				var fileContent:String = fileStream.readMultiByte(fileStream.bytesAvailable,code);
				fileStream.close();
				_content = fileContent;
				parseCSV();
			}

			private function onErrorResult(event:ErrorMessage):void{
				Alert(&quot;删除数据失败！&quot;);
				listowner(curOrg.id);
			}

			private function parseCSV():void{
				var query:Query = entityManager.createQuery(&quot;DELETE FROM Owner o WHERE o.orgID=:orgID&quot;);
				query.setNamedParameter(&quot;orgID&quot;,curOrg.id);
				query.executeUpdate().addResultHandler(successDeleteOwner);
				if(owners!=null &amp;&amp; owners.length&gt;0){
					owners.removeAll();
				}else if(owners==null){
					owners = new ArrayCollection();
				}
			}	

			private function successDeleteOwner(rows:int):void{
				var csvArray:Array = new Array();
				var csvLines:Array = _content.split(String.fromCharCode(13,10));
				csvLines.splice(0,1);
				for each(var s:String in csvLines){
					var lineItems:Array = s.split(&quot;,&quot;);
					var owner:Owner = new Owner();
					owner.homeNumber = lineItems[3];
					owner.orgID = curOrg.id;
					owner.ownerName = lineItems[1];
					owner.propertyID =  lineItems[0];
					owner.smsNumber = lineItems[2];
					owner.remark = lineItems[4];
					entityManager.persist(owner).addResultHandler(successCreatedOwner);
				} 

			} 

			private function successCreatedOwner(owner:Owner):void{
				//nothing to do now
				owners.addItem(owner);
			}

		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:HBox width=&quot;100%&quot; verticalAlign=&quot;middle&quot;&gt;
		&lt;mx:Label text=&quot;选择公司：&quot;/&gt;
		&lt;mx:ComboBox id=&quot;orgList&quot; dataProvider=&quot;{organizations}&quot; labelField=&quot;name&quot; close=&quot;changeOrg()&quot;/&gt;
		&lt;mx:Spacer width=&quot;100%&quot;/&gt;
		&lt;mx:Button label=&quot;清空当前数据并导入新业主资料&quot; click=&quot;browseFile()&quot;/&gt;
	&lt;/mx:HBox&gt;

	&lt;mx:DataGrid width=&quot;100%&quot; dataProvider=&quot;{owners}&quot; height=&quot;100%&quot; id=&quot;ownerDG&quot;&gt;
		&lt;mx:columns&gt;
	         &lt;mx:DataGridColumn dataField=&quot;propertyID&quot; headerText=&quot;房号&quot;/&gt;
	         &lt;mx:DataGridColumn dataField=&quot;ownerName&quot; headerText=&quot;业主姓名&quot;/&gt;
	         &lt;mx:DataGridColumn dataField=&quot;smsNumber&quot; headerText=&quot;短信号码&quot;/&gt;
	         &lt;mx:DataGridColumn dataField=&quot;homeNumber&quot; headerText=&quot;住宅电话&quot;/&gt;
	         &lt;mx:DataGridColumn dataField=&quot;remark&quot; headerText=&quot;备注&quot;/&gt;
	     &lt;/mx:columns&gt;
	&lt;/mx:DataGrid&gt;
&lt;/mx:VBox&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.ityao.com/archives/198/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

