posted @ 2014-10-13 15:57 碼農(nóng)cz 閱讀(113) | 評(píng)論 (0) | 編輯 收藏
posted @ 2014-10-13 15:57 碼農(nóng)cz 閱讀(111) | 評(píng)論 (0) | 編輯 收藏

至此,準(zhǔn)備工作就可以了。
看看頁(yè)面怎么寫的

運(yùn)行,就可以了。
posted @ 2014-10-13 15:50 碼農(nóng)cz 閱讀(164) | 評(píng)論 (0) | 編輯 收藏
posted @ 2012-07-18 14:45 碼農(nóng)cz 閱讀(1271) | 評(píng)論 (0) | 編輯 收藏
1.在action類中,為屬性提供get/set方法。
2.使用javabean的引用,提供get/set方法。但是表單中名字必須是javabean引用的名字.屬性名。
3.實(shí)現(xiàn)Modeldriven接口。
posted @ 2012-07-05 14:59 碼農(nóng)cz 閱讀(182) | 評(píng)論 (0) | 編輯 收藏
posted @ 2012-07-05 14:48 碼農(nóng)cz 閱讀(265) | 評(píng)論 (0) | 編輯 收藏
posted @ 2008-05-15 10:37 碼農(nóng)cz 閱讀(1743) | 評(píng)論 (3) | 編輯 收藏
Map接口: | + -- WeakHashMap: 以弱鍵 實(shí)現(xiàn)的基于哈希表的 Map。在 WeakHashMap 中,當(dāng)某個(gè)鍵不再正常使用時(shí),將自動(dòng)移除其條 | 目。更精確地說(shuō),對(duì)于一個(gè)給定的鍵,其映射的存在并不阻止垃圾回收器對(duì)該鍵的丟棄,這就使該鍵成為可終止的,被終 | 止,然后被回收。丟棄某個(gè)鍵時(shí),其條目從映射中有效地移除,因此,該類的行為與其他的 Map 實(shí)現(xiàn)有所不同。此實(shí)現(xiàn) | 不是同步的。 | + -- TreeMap:該映射根據(jù)其鍵的自然順序進(jìn)行排序,或者根據(jù)創(chuàng)建映射時(shí)提供的 Comparator 進(jìn)行排序,具體取決于使用的 | 構(gòu)造方法。此實(shí)現(xiàn)不是同步的。 | + -- HashMap:基于哈希表的 Map 接口的實(shí)現(xiàn)。此實(shí)現(xiàn)提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了 | 非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順 | 序恒久不變。此實(shí)現(xiàn)不是同步的。 | +-- SortedMap: 進(jìn)一步提供關(guān)于鍵的總體排序 的 Map。該映射是根據(jù)其鍵的自然順序進(jìn)行排序的,或者根據(jù)通常在創(chuàng)建有 序映射時(shí)提供的 Comparator 進(jìn)行排序。對(duì)有序映射的 collection 視圖(由 entrySet、keySet 和 values 方法返回 )進(jìn)行迭代時(shí),此順序就會(huì)反映出來(lái)。要采用此排序方式,還需要提供一些其他操作(此接口是 SortedSet 的對(duì)應(yīng)映 射)。 Collection接口: | + -- Set接口:一個(gè)不包含重復(fù)元素的 collection。更正式地說(shuō),set 不包含滿足 e1.equals(e2) 的元素對(duì) e1 和 e2,并 | | 且最多包含一個(gè) null 元素。正如其名稱所暗示的,此接口模仿了數(shù)學(xué)上的 set 抽象。 | | | + -- HashSet:此類實(shí)現(xiàn) Set 接口,由哈希表(實(shí)際上是一個(gè) HashMap 實(shí)例)支持。它不保證 set 的迭代順序; | | 特別是它不保證該順序恒久不變。此類允許使用 null 元素。此類為基本操作提供了穩(wěn)定性能,此實(shí)現(xiàn)不是同 | | 步的。 | | | + -- LinkedHashSet:具有可預(yù)知迭代順序的 Set 接口的哈希表和鏈接列表實(shí)現(xiàn)。此實(shí)現(xiàn)與 HashSet 的不同之外在 | | 于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,即按照將元素插入到 set | | 中 的順序(插入順序)進(jìn)行迭代。注意,插入順序不 受在 set 中重新插入的 元素的影響。此實(shí)現(xiàn)不是同步 | | 的。 | | | + -- TreeSet:基于 TreeMap 的 NavigableSet 實(shí)現(xiàn)。使用元素的自然順序?qū)υ剡M(jìn)行排序,或者根據(jù)創(chuàng)建 set 時(shí) | 提供的 Comparator 進(jìn)行排序,具體取決于使用的構(gòu)造方法。此實(shí)現(xiàn)為基本操作(add、remove 和 contains) | 提供受保證的 log(n) 時(shí)間開(kāi)銷。此實(shí)現(xiàn)不是同步的。 | + -- List接口:有序的 collection(也稱為序列)。此接口的用戶可以對(duì)列表中每個(gè)元素的插入位置進(jìn)行精確地控制。用戶 | 可以根據(jù)元素的整數(shù)索引(在列表中的位置)訪問(wèn)元素,并搜索列表中的元素。 | + -- ArrayList:List 接口的大小可變數(shù)組的實(shí)現(xiàn)。實(shí)現(xiàn)了所有可選列表操作,并允許包括 null 在內(nèi)的所有元素。 | 除了實(shí)現(xiàn) List 接口外,此類還提供一些方法來(lái)操作內(nèi)部用來(lái)存儲(chǔ)列表的數(shù)組的大小。(此類大致上等同于 | Vector 類,除了此類是不同步的。)每個(gè) ArrayList 實(shí)例都有一個(gè)容量。該容量是指用來(lái)存儲(chǔ)列表元素的數(shù) | 組的大小。它總是至少等于列表的大小。隨著向 ArrayList 中不斷添加元素,其容量也自動(dòng)增長(zhǎng)。并未指定增 | 長(zhǎng)策略的細(xì)節(jié),因?yàn)檫@不只是添加元素會(huì)帶來(lái)分?jǐn)偣潭〞r(shí)間開(kāi)銷那樣簡(jiǎn)單。此實(shí)現(xiàn)不是同步的。 | + -- LinkedList:List 接口的鏈接列表實(shí)現(xiàn)。實(shí)現(xiàn)所有可選的列表操作,并且允許所有元素(包括 null)。除了實(shí) | 現(xiàn) List 接口外,LinkedList 類還為在列表的開(kāi)頭及結(jié)尾 get、remove 和 insert 元素提供了統(tǒng)一的命名方 | 法。這些操作允許將鏈接列表用作堆棧、隊(duì)列或雙端隊(duì)列。提供先進(jìn)先出隊(duì)列操作(FIFO)。此實(shí)現(xiàn)不是同步的。 | + -- Vector:Vector 類可以實(shí)現(xiàn)可增長(zhǎng)的對(duì)象數(shù)組。與數(shù)組一樣,它包含可以使用整數(shù)索引進(jìn)行訪問(wèn)的組件。但是 ,Vector 的大小可以根據(jù)需要增大或縮小,以適應(yīng)創(chuàng)建 Vector 后進(jìn)行添加或移除項(xiàng)的操作。此實(shí)現(xiàn)是同步的 。 |
posted @ 2007-04-18 11:18 碼農(nóng)cz 閱讀(332) | 評(píng)論 (0) | 編輯 收藏
Tomcat 5.5 uses Commons Logging throughout its internal code allowing the developer to choose a logging configuration that suits their needs, e.g java.util.logging or Log4J. Commons Logging provides Tomcat the ability to log hierarchially across various log levels without needing to rely on a particular logging implementation.
An important consequence for Tomcat 5.5 is that the <Logger> element found in previous versions to create a localhost_log
is no longer a valid nested element of <Context>. Instead, the default Tomcat configuration will use java.util.logging. If the developer wishes to collect detailed internal Tomcat logging (i.e what is happening within the Tomcat engine), then they should configure a logging system such as java.util.logging or log4j as detailed next
習(xí)慣用log4j來(lái)配置log信息的輸出。
新建log4j.properties,內(nèi)容為
log4j.rootLogger=info,Console,R
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
#log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.appender.Console.layout.ConversionPattern=%d{yy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/tomcat.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy.MM.dd HH:mm:ss} %5p %c{1}(%L):? %m%n
log4j.logger.org.apache=info, R
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=DEBUG, R
log4j.logger.org.apache.catalina.core=info, R
log4j.logger.org.apache.catalina.session=info, R
最后四行是tomcat的信息,如果改為debug日志文件將十分龐大。
將這個(gè)文件放入${catalina.home}/common/classes下,再將log4j.jar和commons-logging.jar放入${catalina.home}/common/lib下,就可以在${catalina.home}/logs/下見(jiàn)到日志了。
posted @ 2007-01-09 18:42 碼農(nóng)cz 閱讀(1405) | 評(píng)論 (0) | 編輯 收藏
我在做項(xiàng)目時(shí)曾碰到這個(gè)問(wèn)題,怎樣動(dòng)態(tài)地添加一個(gè)文本框或文件域,這在網(wǎng)上很容易找到。但對(duì)怎樣處理提交的動(dòng)態(tài)數(shù)據(jù)就很少有這方面的信息了。本人翻閱了一些資料,把自己的方法寫了下來(lái),以饗讀者。
1.提交表單
?



































?
2.處理數(shù)據(jù)




























posted @ 2007-01-04 14:44 碼農(nóng)cz 閱讀(1429) | 評(píng)論 (1) | 編輯 收藏
??? 一,servlet容器對(duì)url的匹配過(guò)程:
?????
當(dāng)一個(gè)請(qǐng)求發(fā)送到servlet容器的時(shí)候,容器先會(huì)將請(qǐng)求的url減去當(dāng)前應(yīng)用上下文的路徑作為servlet的映射url,比如我訪問(wèn)的是http://localhost/test/aaa.html,我的應(yīng)用上下文是test,容器會(huì)將http://localhost/test去掉,剩下的/aaa.html部分拿來(lái)做servlet的映射匹配。這個(gè)映射匹配過(guò)程是有順序的,而且當(dāng)有一個(gè)servlet匹配成功以后,就不會(huì)去理會(huì)剩下的servlet了(filter不同,后文會(huì)提到)。其匹配規(guī)則和順序如下: 1.???? 精確路徑匹配。例子:比如servletA 的url-pattern為 /test,servletB的url-pattern為/* ,這個(gè)時(shí)候,如果我訪問(wèn)的url為http://localhost/test,這個(gè)時(shí)候容器就會(huì)先進(jìn)行精確路徑匹配,發(fā)現(xiàn)/test正好被servletA精確匹配,那么就去調(diào)用servletA,也不會(huì)去理會(huì)其他的servlet了。 2.???? 最長(zhǎng)路徑匹配。例子:servletA的url-pattern為/test/*,而servletB的url-pattern為/test/a/*,此時(shí)訪問(wèn)http://localhost/test/a時(shí),容器會(huì)選擇路徑最長(zhǎng)的servlet來(lái)匹配,也就是這里的servletB。 3.???? 擴(kuò)展匹配,如果url最后一段包含擴(kuò)展,容器將會(huì)根據(jù)擴(kuò)展選擇合適的servlet。例子:servletA的url-pattern:*.action 4.???? 如果前面三條規(guī)則都沒(méi)有找到一個(gè)servlet,容器會(huì)根據(jù)url選擇對(duì)應(yīng)的請(qǐng)求資源。如果應(yīng)用定義了一個(gè)default servlet,則容器會(huì)將請(qǐng)求丟給default servlet(什么是default servlet?后面會(huì)講)。 |
???? 根據(jù)這個(gè)規(guī)則表,就能很清楚的知道servlet的匹配過(guò)程,所以定義servlet的時(shí)候也要考慮url-pattern的寫法,以免出錯(cuò)。
????? 對(duì)于filter,不會(huì)像servlet那樣只匹配一個(gè)servlet,因?yàn)?/span>filter的集合是一個(gè)鏈,所以只會(huì)有處理的順序不同,而不會(huì)出現(xiàn)只選擇一個(gè)filter。Filter的處理順序和filter-mapping在web.xml中定義的順序相同。
??? 二,url-pattern詳解
???????? 在web.xml文件中,以下語(yǔ)法用于定義映射:
l? 以”/’開(kāi)頭和以”/*”結(jié)尾的是用來(lái)做路徑映射的。
l? 以前綴”*.”開(kāi)頭的是用來(lái)做擴(kuò)展映射的。
l? “/” 是用來(lái)定義default servlet映射的。
l? 剩下的都是用來(lái)定義詳細(xì)映射的。比如: /aa/bb/cc.action
所以,為什么定義”/*.action”這樣一個(gè)看起來(lái)很正常的匹配會(huì)錯(cuò)?因?yàn)檫@個(gè)匹配即屬于路徑映射,也屬于擴(kuò)展映射,導(dǎo)致容器無(wú)法判斷。
posted @ 2006-12-18 10:45 碼農(nóng)cz 閱讀(387) | 評(píng)論 (0) | 編輯 收藏
使用servlet來(lái)下載文件,其原理非常簡(jiǎn)單,只要得到文件的輸入流(或相應(yīng)字節(jié)),然后寫輸出流即可。現(xiàn)就其中的幾個(gè)細(xì)節(jié)問(wèn)題展開(kāi):
1. MIME類型的設(shè)置:
Web 瀏覽器使用 MIME 類型來(lái)識(shí)別非 HTML 文檔,并決定如何顯示該文檔內(nèi)的數(shù)據(jù)。
例如EXCEL文件的 MIME 類型是 "application/vnd.ms-excel "。要用servlet 來(lái)打開(kāi)一個(gè) EXCEL 文檔,需要將 response 對(duì)象中 header 的 contentType 設(shè)置成“application/vnd.ms-excel ”。
response.setContentType(contentType);
2. Content disposition
HTTP response header中的content-disposition 允許 servlet 指定文檔表示的信息。使用這種header ,你就可以將文檔指定成單獨(dú)打開(kāi)(而不是在瀏覽器中打開(kāi)),還可以根據(jù)用戶的操作來(lái)顯示。
如果用戶要保存文檔,你還可以為該文檔建議一個(gè)文件名。這個(gè)建議名稱會(huì)出現(xiàn)在 Save As 對(duì)話框的“文件名”欄中。如果沒(méi)有指定,則對(duì)話框中就會(huì)出現(xiàn) servlet 的名字。
servlet 中,將 header 設(shè)置成下面這樣:
response.setHeader("Content-disposition","attachment;filename="+ "Example.xls" );
response.setHeader("Content-Disposition", "inline; filename="fliename)
點(diǎn)擊打開(kāi)會(huì)在ie中打開(kāi)。
需要說(shuō)明的有三點(diǎn):
? 中文文件名需要進(jìn)行iso8859-1轉(zhuǎn)碼方可正確顯示:
fileName = new String(fileName.getBytes("GBK"),"iso8859-1");
? 傳遞的文件名,需要包含后綴名(如果此文件有后綴名),否則丟失文件的屬性,而不能自行選擇相關(guān)程序打開(kāi)。
? 有下載前詢問(wèn)(是打開(kāi)文件還是保存到計(jì)算機(jī))和通過(guò)IE瀏覽器直接選擇相關(guān)應(yīng)用程序插件打開(kāi)兩種方式,前者如上代碼所示,后者如下:
response.setHeader("Content-disposition","filename="+ "Example.xls" );
3. 在研究文件的上傳及下載過(guò)程中,有幾點(diǎn)體會(huì)
程序的I/O操作往往是性能的瓶頸所在,java io定義了兩個(gè)基本的抽象類:InputStream和OutputStream,對(duì)于不同的數(shù)據(jù)類型比如磁盤,網(wǎng)絡(luò)又提供了不同的實(shí)現(xiàn),java.io也提供了一些緩沖流(BufferedStream),使硬盤可以很快的讀寫一大塊的數(shù)據(jù), 而Java基本的I/O類一次只能讀寫一個(gè)字節(jié),但緩沖流(BufferedStream)可以一次讀寫一批數(shù)據(jù),,緩沖流(Buffered Stream)大大提高了I/O的性能。所以:
?小塊小塊的讀寫數(shù)據(jù)會(huì)非常慢,因此,盡量大塊的讀寫數(shù)據(jù)
?使用BufferedInputStream和BufferedOutputStream來(lái)批處理數(shù)據(jù)以提高性能
?對(duì)象的序列化(serialization)非常影響I/O的性能,盡量少用
posted @ 2006-12-18 10:41 碼農(nóng)cz 閱讀(199) | 評(píng)論 (0) | 編輯 收藏
一、saveorUpdate與unsaved-value
到底是sava還是update
Hibernate需要判斷被操作的對(duì)象究竟是一個(gè)已經(jīng)持久化過(guò)的持久對(duì)象還是臨時(shí)對(duì)象。
1).主鍵Hibernate的id generator產(chǎn)生
<id name="id" type="java.lang.Long">
<column name="ID" precision="22" scale="0" />
<generator class="increment" />
</id>
Project project = new Project();
project.setId(XXX);
this.projectDao.saveOrUpdate(project);
1、默認(rèn)unsaved-value="null"
主鍵是對(duì)象類型,hebernate判斷project的主鍵是否位null,來(lái)判斷project是否已被持久化
是的話,對(duì)project對(duì)象發(fā)送save(project),
若自己設(shè)置了主鍵則直接生成update的sql,發(fā)送update(project),即便數(shù)據(jù)庫(kù)里沒(méi)有那條記錄。
主鍵是基本類型如int/long/double/
自己設(shè)置unsaved-null="0"。
所以這樣的話save和update操作肯定不會(huì)報(bào)錯(cuò)。
2、unsaved-value="none",
由于不論主鍵屬性為任何值,都不可能為none,因此Hibernate總是對(duì)project對(duì)象發(fā)送update(project)
3、unsaved-value="any"
由于不論主鍵屬性為任何值,都肯定為any,因此Hibernate總是對(duì)project對(duì)象發(fā)送save(project),hibernate生成主鍵。
Hibernate文檔中寫到
saveOrUpdate()完成了如下工作:
如果對(duì)象已經(jīng)在這個(gè)session中持久化過(guò)了,什么都不用做
如果對(duì)象沒(méi)有標(biāo)識(shí)值,調(diào)用save()來(lái)保存它
如果對(duì)象的標(biāo)識(shí)值與unsaved-value中的條件匹配,調(diào)用save()來(lái)保存它
如果對(duì)象使用了版本(version或timestamp),那么除非設(shè)置unsaved-value="undefined",版本檢查會(huì)發(fā)生在標(biāo)識(shí)符檢查之前.
如果這個(gè)session中有另外一個(gè)對(duì)象具有同樣的標(biāo)識(shí)符,拋出一個(gè)異常
2).主鍵由自己來(lái)賦值
<id name="id" type="java.lang.Long">
<column name="ID" precision="22" scale="0" />
<generator class="assigned" />
</id>
Project project = new Project();
project.setId(XXX);
this.projectDao.saveOrUpdate(project);
1、默認(rèn)unsaved-value="null"
這時(shí)有所不同,hibernate會(huì)根據(jù)主鍵產(chǎn)生一個(gè)select,來(lái)判斷此對(duì)象是否已被持久化
已被持久化則update,未被持久化則save。
2、unsaved-value="none",update對(duì)象,同上
3、unsaved-value="any" ,save對(duì)象,
如果自己自己設(shè)置的ID在數(shù)據(jù)庫(kù)中已存在,則報(bào)錯(cuò)。
二、save與update操作
顯式的使用session.save()或者session.update()操作一個(gè)對(duì)象的時(shí)候,實(shí)際上是用不到unsaved-value的
在同一Session,save沒(méi)什么可說(shuō)得
update對(duì)象時(shí), 最直接的更改一個(gè)對(duì)象的方法就是load()它,保持Session打開(kāi),然后直接修改即可:
Session s =…
Project p = (Project) sess.load(Project.class, id) );
p.setName(“test”);
s.flush();
不用調(diào)用s.update(p);hibernate能察覺(jué)到它的變化,會(huì)自動(dòng)更新。當(dāng)然顯示調(diào)用的話也不會(huì)錯(cuò)
Hibernate文檔中寫到
update()方法在下列情形下使用:
程序在前面的session中裝載了對(duì)象
對(duì)象被傳遞到UI(界面)層
對(duì)該對(duì)象進(jìn)行了一些修改
對(duì)象被傳遞回業(yè)務(wù)層
應(yīng)用程序在第二個(gè)session中調(diào)用update()保存修改
三、delete操作
刪除時(shí)直接自己構(gòu)造一個(gè)project即可刪除
this.projectDao.delete(preojct);
以前刪除我是這樣寫的
public void deleteProject(String id) {
Project project = (Project) this.projectDao.get(Project.class, id);
if (project != null) {
this.projectDao.delete(project);
}
即這樣也是可以的
Project project = new Project();
project.setId(id);
this.projectDao.delete(project).
如果有級(jí)聯(lián)關(guān)系,需要把級(jí)聯(lián)的子類也構(gòu)造出來(lái)add進(jìn)去,同樣可以刪除。
好了,羅嗦的夠多了。
posted @ 2006-12-18 10:40 碼農(nóng)cz 閱讀(507) | 評(píng)論 (0) | 編輯 收藏
1、遍歷workbook
代碼
2、得到列和單元格
代碼
3、設(shè)置sheet名稱和單元格內(nèi)容為中文
代碼
4、單元格內(nèi)容未公式或數(shù)值,可以這樣讀寫
代碼
代碼
代碼
7、常用方法
代碼
8、常用單元格邊框格式
虛線HSSFCellStyle.BORDER_DOTTED 代碼
9、設(shè)置字體和內(nèi)容位置 代碼
10、插入圖片 論壇里看到的 代碼
|
posted @ 2006-12-18 10:36 碼農(nóng)cz 閱讀(612) | 評(píng)論 (0) | 編輯 收藏
一.POI簡(jiǎn)介
Jakarta POI 是apache的子項(xiàng)目,目標(biāo)是處理ole2對(duì)象。它提供了一組操縱Windows文檔的Java API
目前比較成熟的是HSSF接口,處理MS Excel(97-2002)對(duì)象。它不象我們僅僅是用csv生成的沒(méi)有格式的可以由Excel轉(zhuǎn)換的東西,而是真正的Excel對(duì)象,你可以控制一些屬性如sheet,cell等等。
二.HSSF概況
HSSF 是Horrible SpreadSheet Format的縮寫,也即“討厭的電子表格格式”。也許HSSF的名字有點(diǎn)滑稽,就本質(zhì)而言它是一個(gè)非常嚴(yán)肅、正規(guī)的API。通過(guò)HSSF,你可以用純Java代碼來(lái)讀取、寫入、修改Excel文件。
HSSF 為讀取操作提供了兩類API:usermodel和eventusermodel,即“用戶模型”和“事件-用戶模型”。前者很好理解,后者比較抽象,但操作效率要高得多。
三.開(kāi)始編碼
1 . 準(zhǔn)備工作
要求:JDK 1.4+POI開(kāi)發(fā)包
可以到 http://www.apache.org/dyn/closer.cgi/jakarta/poi/ 最新的POI工具包
2 . EXCEL 結(jié)構(gòu)
HSSFWorkbook excell 文檔對(duì)象介紹
HSSFSheet excell的表單
HSSFRow excell的行
HSSFCell excell的格子單元
HSSFFont excell字體
HSSFName 名稱
HSSFDataFormat 日期格式
在poi1.7中才有以下2項(xiàng):
HSSFHeader sheet頭
HSSFFooter sheet尾
和這個(gè)樣式
HSSFCellStyle cell樣式
輔助操作包括
HSSFDateUtil 日期
HSSFPrintSetup 打印
HSSFErrorConstants 錯(cuò)誤信息表
3 .具體用法實(shí)例 (采用 usermodel )
如何讀Excel
讀取Excel文件時(shí),首先生成一個(gè)POIFSFileSystem對(duì)象,由POIFSFileSystem對(duì)象構(gòu)造一個(gè)HSSFWorkbook,該HSSFWorkbook對(duì)象就代表了Excel文檔。下面代碼讀取上面生成的Excel文件寫入的消息字串:
try{
?? POIFSFileSystem fs=new POIFSFileSystem(new FileInputStream("d:/workbook.xls"));
?? HSSFWorkbook wb = new HSSFWorkbook(fs);
?? HSSFSheet sheet = wb.getSheetAt(0);
?? HSSFRow row = sheet.getRow(0);
?? HSSFCell cell = row.getCell((short) 0);
?? String msg = cell.getStringCellValue();
?? System.out.println(msg);
? }catch(Exception e){
?? e.printStackTrace();
? }
如何寫excel,
將excel的第一個(gè)表單第一行的第一個(gè)單元格的值寫成“a test”。
POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream("workbook.xls"));
??? HSSFWorkbook wb = new HSSFWorkbook(fs);
??? HSSFSheet sheet = wb.getSheetAt(0);
??? HSSFRow row = sheet.getRow(0);
??? HSSFCell cell = row.getCell((short)0);
??? cell.setCellValue("a test");
??? // Write the output to a file
??? FileOutputStream fileOut = new FileOutputStream("workbook.xls");
??? wb.write(fileOut);
fileOut.close();
4 . 可參考文檔
POI 主頁(yè): http://jakarta.apache.org/poi/ ,
初學(xué)者如何快速上手使用POI HSSF
http://jakarta.apache.org/poi/hssf/quick-guide.html 。
里面有很多例子代碼,可以很方便上手。
四.使用心得
POI HSSF 的usermodel包把Excel文件映射成我們熟悉的結(jié)構(gòu),諸如Workbook、Sheet、Row、Cell等,它把整個(gè)結(jié)構(gòu)以一組對(duì)象的形式保存在內(nèi)存之中,便于理解,操作方便,基本上能夠滿足我們的要求,所以說(shuō)這個(gè)一個(gè)不錯(cuò)的選擇。
-------------------------------
前面已經(jīng)講過(guò)利用POI讀寫Excel,下面是一個(gè)用POI向Excel中插入圖片的例子。
官方文檔:
Images are part of the drawing support. To add an image just call createPicture() on the drawing patriarch. At the time of writing the following types are supported:
PNG
JPG
DIB
It is not currently possible to read existing images and it should be noted that any existing drawings may be erased once you add a image to a sheet.
// Create the drawing patriarch. This is the top level container for
// all shapes. This will clear out any existing shapes for that sheet.
通過(guò)HSSFPatriarch類createPicture方法的在指定的wb中的sheet創(chuàng)建圖片,它接受二個(gè)參數(shù),第一個(gè)是HSSFClientAnchor,設(shè)定圖片的大小。

?2

?3

?4

?5

?6

?7

?8

?9

10

11

12

13

14

15

16



17

18



19

20

21

22



23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49



50

51

52

53



54

55



56

57



58

59

60

61



62

63

64

65

66

67

68

posted @ 2006-12-18 10:35 碼農(nóng)cz 閱讀(1868) | 評(píng)論 (2) | 編輯 收藏
目前整個(gè)開(kāi)發(fā)社區(qū)對(duì)AOP(Aspect Oriented Programing)推崇備至,也涌現(xiàn)出大量支持AOP的優(yōu)秀Framework,--Spring, JAC, Jboss AOP 等等。AOP似乎一時(shí)之間成了潮流。Java初學(xué)者不禁要發(fā)出感慨,OOP還沒(méi)有學(xué)通呢,又來(lái)AOP。本文不是要在理論上具體闡述何為AOP, 為何要進(jìn)行AOP . 要詳細(xì)了解學(xué)習(xí)AOP可以到它老家http://aosd.net去瞧瞧。這里只是意圖通過(guò)一個(gè)簡(jiǎn)單的例子向初學(xué)者展示一下如何來(lái)進(jìn)行AOP.
為了簡(jiǎn)單起見(jiàn),例子沒(méi)有沒(méi)有使用任何第三方的AOP Framework, 而是利用Java語(yǔ)言本身自帶的動(dòng)態(tài)代理功能來(lái)實(shí)現(xiàn)AOP.
讓我們先回到AOP本身,AOP主要應(yīng)用于日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理等方面。它的主要意圖就要將日志記錄,性能統(tǒng)計(jì),安全控制等等代碼從商業(yè)邏輯代碼中清楚的劃分出來(lái),我們可以把這些行為一個(gè)一個(gè)單獨(dú)看作系統(tǒng)所要解決的問(wèn)題,就是所謂的面向問(wèn)題的編程(不知將AOP譯作面向問(wèn)題的編程是否欠妥)。通過(guò)對(duì)這些行為的分離,我們希望可以將它們獨(dú)立地配置到商業(yè)方法中,而要改變這些行為也不需要影響到商業(yè)方法代碼。
假設(shè)系統(tǒng)由一系列的BusinessObject所完成業(yè)務(wù)邏輯功能,系統(tǒng)要求在每一次業(yè)務(wù)邏輯處理時(shí)要做日志記錄。這里我們略去具體的業(yè)務(wù)邏輯代碼。
public interface BusinessInterface {
public void processBusiness();
}
public class BusinessObject implements BusinessInterface {
private Logger logger = Logger.getLogger(this.getClass().getName());
public void processBusiness(){
try {
logger.info("start to processing...");
//business logic here.
System.out.println(“here is business logic”);
logger.info("end processing...");
} catch (Exception e){
logger.info("exception happends...");
//exception handling
}
}
}
這里處理商業(yè)邏輯的代碼和日志記錄代碼混合在一起,這給日后的維護(hù)帶來(lái)一定的困難,并且也會(huì)造成大量的代碼重復(fù)。完全相同的log代碼將出現(xiàn)在系統(tǒng)的每一個(gè)BusinessObject中。
按照AOP的思想,我們應(yīng)該把日志記錄代碼分離出來(lái)。要將這些代碼分離就涉及到一個(gè)問(wèn)題,我們必須知道商業(yè)邏輯代碼何時(shí)被調(diào)用,這樣我們好插入日志記錄代碼。一般來(lái)說(shuō)要截獲一個(gè)方法,我們可以采用回調(diào)方法或者動(dòng)態(tài)代理。動(dòng)態(tài)代理一般要更加靈活一些,目前多數(shù)的AOP Framework也大都采用了動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)。這里我們也采用動(dòng)態(tài)代理作為例子。
JDK1.2以后提供了動(dòng)態(tài)代理的支持,程序員通過(guò)實(shí)現(xiàn)java.lang.reflect.InvocationHandler接口提供一個(gè)執(zhí)行處理器,然后通過(guò)java.lang.reflect.Proxy得到一個(gè)代理對(duì)象,通過(guò)這個(gè)代理對(duì)象來(lái)執(zhí)行商業(yè)方法,在商業(yè)方法被調(diào)用的同時(shí),執(zhí)行處理器會(huì)被自動(dòng)調(diào)用。
有了JDK的這種支持,我們所要做的僅僅是提供一個(gè)日志處理器。
public class LogHandler implements InvocationHandler {
private Logger logger = Logger.getLogger(this.getClass().getName());
private Object delegate;
public LogHandler(Object delegate){
this.delegate = delegate;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o = null;
try {
logger.info("method stats..." + method);
o = method.invoke(delegate,args);
logger.info("method ends..." + method);
} catch (Exception e){
logger.info("Exception happends...");
//excetpion handling.
}
return o;
}
}
現(xiàn)在我們可以把BusinessObject里面的所有日志處理代碼全部去掉了。
public class BusinessObject implements BusinessInterface {
private Logger logger = Logger.getLogger(this.getClass().getName());
public void processBusiness(){
//business processing
System.out.println(“here is business logic”);
}
}
客戶端調(diào)用商業(yè)方法的代碼如下:
BusinessInterface businessImp = new BusinessObject();
InvocationHandler handler = new LogHandler(businessImp);
BusinessInterface proxy = (BusinessInterface) Proxy.newProxyInstance(
businessImp.getClass().getClassLoader(),
businessImp.getClass().getInterfaces(),
handler);
proxy.processBusiness();
程序輸出如下:
INFO: method stats...
here is business logic
INFO: method ends...
至此我們的第一次小嘗試算是完成了。可以看到,采用AOP之后,日志記錄和業(yè)務(wù)邏輯代碼完全分開(kāi)了,以后要改變?nèi)罩居涗浀脑捴恍枰薷娜罩居涗浱幚砥骶托辛耍鴺I(yè)務(wù)對(duì)象本身(BusinessObject)無(wú)需做任何修改。并且這個(gè)日志記錄不會(huì)造成重復(fù)代碼了,所有的商業(yè)處理對(duì)象都可以重用這個(gè)日志處理器。
當(dāng)然在實(shí)際應(yīng)用中,這個(gè)例子就顯得太粗糙了。由于JDK的動(dòng)態(tài)代理并沒(méi)有直接支持一次注冊(cè)多個(gè)InvocationHandler,那么我們對(duì)業(yè)務(wù)處理方法既要日志記錄又要性能統(tǒng)計(jì)時(shí),就需要自己做一些變通了。一般我們可以自己定義一個(gè)Handler接口,然后維護(hù)一個(gè)隊(duì)列存放所有Handler, 當(dāng)InvocationHandler被觸發(fā)的時(shí)候我們依次調(diào)用自己的Handler。所幸的是目前幾乎所有的AOP Framework都對(duì)這方面提供了很好的支持.這里推薦大家使用Spring。
posted @ 2006-12-13 11:43 碼農(nóng)cz 閱讀(225) | 評(píng)論 (0) | 編輯 收藏