- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > 編程語(yǔ)言 >
- Java中怎么操作Office對象
本篇內容主要講解“Java中怎么操作Office對象”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強。下面就讓小編來(lái)帶大家學(xué)習“Java中怎么操作Office對象”吧!
Java中使用JCOM操作Office對象[]
通過(guò)使用COM技術(shù),我們用微軟Office應用程序能夠建立很多應用程序擴展,但是Java開(kāi)發(fā)人員卻無(wú)法享受它帶來(lái)的便利--除非他們擁有方便的Java訪(fǎng)問(wèn)COM的途徑(Java-to-COM橋)。使用JCom的時(shí)候,你可以在Java中控制幾乎所有的COM對象,而且它還帶有一些用于Excel的強大的輔助類(lèi)。
在你每次編寫(xiě)用HTML表格樣式或Java表格對象顯示數據的應用程序的時(shí)候,通常都需要帶有"導出到Excel"功能。那么頭疼的問(wèn)題就出現了。怎么樣實(shí)現這種功能呢?在HTML中顯示的可以在Office 2003中處理嗎?沒(méi)有這么好!你還必須支持Office 97!
你只能去找一個(gè)符合當前需求的工具了,但是接著(zhù)收到更多的要求了。"這能在Word中做到嗎?Powerpoint能做到嗎?能不能用調制解調器撥號到遠程上并發(fā)布數據?Java無(wú)法實(shí)現這些功能是什么意思???Java可以實(shí)現任何功能。"
感謝作為Java和COM橋梁的框架組件,它使你在遇到這些情況的時(shí)候都可以回答"Yes"。Java-COM橋梁使你能夠根據自己的需要操作Windows組件--以前這是VB、C++和.NET開(kāi)發(fā)人員的領(lǐng)地。你通過(guò)實(shí)現一個(gè)與DCOM后端(back end)對話(huà)的Java前端(front end),可以遠離端對端(end-to-end)的COM系統。在本文的末尾,你可以使用其中一個(gè)Java-to-COM橋:它可以被命名為JCom。
Excel基礎知識
開(kāi)始之前,你需要首先從Sourceforge網(wǎng)站下載API。它包含了JCom所使用的Java類(lèi)的所有源代碼、C++代碼和JCom用于配置Java和COM的編譯好的DLL。把這個(gè)DLL放到你的Java主目錄的/bin/目錄下面,否則會(huì )出現問(wèn)題。同時(shí),為了不出現問(wèn)題,還要正確地設置JAVA_HOME環(huán)境變量。JCom的大多數文檔目前都是用日語(yǔ)寫(xiě)的,但是翻譯工作正在進(jìn)行中,因此以后會(huì )有些改進(jìn)的。
下載和安裝過(guò)程完成以后,用列表1中的代碼試一試。這段代碼會(huì )建立到Excel的JCom接口,并把"Hello World"寫(xiě)入第一個(gè)單元格中。你可以看到如圖1所示的結果。盡管JCom是一個(gè)通用的COM類(lèi)庫,但是還是帶有很多用于Excel的輔助類(lèi),這是因為Excel可能是最常用的自動(dòng)化COM應用程序。這些輔助類(lèi)可以為我們節省很多時(shí)間,它們使JCOM成為一個(gè)更好的類(lèi)庫了。
列表1:開(kāi)始使用JCOM和Excel
import jp.ne.so_net.ga2.no_ji.jcom.excel8.*;
import jp.ne.so_net.ga2.no_ji.jcom.*;
public class testSimple
{
public static void main(String[] args) throws Exception {
ReleaseManager rm = new ReleaseManager();
try {
System.out.println("EXCEL is Starting...");
ExcelApplication excel = new ExcelApplication(rm);
excel.Visible(true);
ExcelWorkbooks xlBooks = excel.Workbooks();
ExcelWorkbook xlBook = xlBooks.Add();
ExcelWorksheets xlSheets = xlBook.Worksheets();
ExcelWorksheet xlSheet = xlSheets.Item(1);
ExcelRange xlRange = xlSheet.Cells();
xlRange.Item(1,1).Value("Hello, World!" );
}
catch(Exception e) { e.printStackTrace(); }
finally { rm.release(); }
}
}
圖1:Java中使用Excel的第一個(gè)COM自動(dòng)化
如果曾經(jīng)使用VB或VBA來(lái)自動(dòng)化Excel,那么你應該很熟悉列表1中的代碼了。ExcelApplication類(lèi)暴露了Workbooks()屬性,它列舉出Excel中當前打開(kāi)的工作?。╳orkbook),并允許你向運行的Excel副本增加或刪除工作薄。使用.Add()方法增加工作薄,這個(gè)方法會(huì )返回一個(gè)工作薄的引用。
在Excel中工作薄用于保存輸入的數據。工作薄是XLS文件的基礎。一個(gè)工作薄由多個(gè)工作表(worksheet,在圖1中有三個(gè)工作表,分別叫做Sheet1、Sheet2和Sheet3)。工作表通過(guò)Item屬性來(lái)枚舉。你可以使用這個(gè)屬性訪(fǎng)問(wèn)特定的工作表。在圖1中,Sheet 1是第一個(gè)工作表,因此你可以使用xlSheets.Item(1)來(lái)獲取對它的引用。
有了工作表之后,你就可以使用range(范圍)來(lái)操作它上面的數據。Range是一個(gè)單元格或多個(gè)單元格。例如,單元格A1可以使用range (1,1)來(lái)引用,接著(zhù)可以使用Value屬性把數據載入單元格中。
更有意義的例子
假設你希望把Excel作為數據庫中某些數據的表現層。在Java中你希望通過(guò)JDBC獲取數據,并把數據顯示在Excel前端。這種假設是很好的,因為復雜業(yè)務(wù)邏輯中的用例(use case)已經(jīng)用Excel前端顯示了,更不用說(shuō)工作流中的其它的數據項的顯示和交互操作了?,F在你不需要了解業(yè)務(wù)邏輯或分析,就可以使用原始的電子表格,并使用Java中的自動(dòng)化來(lái)"填充它們之間的裂痕"。
我將給出一個(gè)演示這種操作的簡(jiǎn)單示例:本文下載中所包含的內容是建立比較銷(xiāo)售行為的一個(gè)簡(jiǎn)單的數據庫的。它有三個(gè)表:
· Sales是銷(xiāo)售的細節信息,包括銷(xiāo)售項、數量、銷(xiāo)售價(jià)格、是誰(shuí)銷(xiāo)售的以及銷(xiāo)售地區。
· People包含銷(xiāo)售人員的姓名和傭金。
· Districts包含了銷(xiāo)售地區的名稱(chēng)和稅率。
生成報表的時(shí)候,你需要使用下面的業(yè)務(wù)邏輯來(lái)算出真正的數值:
· 毛銷(xiāo)售額等于銷(xiāo)售項乘以銷(xiāo)售價(jià)格加上地稅金額。
· 純銷(xiāo)售額等于毛銷(xiāo)售額減去銷(xiāo)售人員提取的稅前傭金。
這都是一些在Java中可以實(shí)現的簡(jiǎn)單直接的計算過(guò)程,但是我在本文中使用它們的目的是演示如何把這些數據寫(xiě)入Excel電子表格并讓Excel自動(dòng)計算。對于更復雜的情況(使用了更復雜的Excel公式),原理也是一樣的。
此外,下載的內容中還包含了如圖2所示的電子表格。它是作為"模板"供你填充適當的數據的電子表格。
圖2:用于前端填充數據的Excel模板
使用JCOM的時(shí)候,查詢(xún)數據庫中所有銷(xiāo)售數據需要使用下面的SQL:
SELECT sales.id, sales.description, sales.quantity, sales.price, districts.districtname,districts.salestax,people.name,people.commission
FROM 'sales','districts','people'
WHERE (sales.district = districts.id) AND (sales.salesperson = people.id)
接著(zhù)使用自動(dòng)化(automation)把每條記錄都寫(xiě)入Excel電子表格的適當的列中。下載的內容中包含了完整的代碼(列表2所示)。在下面的部分,我將為你解釋代碼中使用JCOM的自動(dòng)化部分。
列表2:從數據庫中獲取數據并載入Excel中的代碼
// 首先建立Excel的引用
ExcelApplication excel = new ExcelApplication(rm);
// 使它可視
excel.Visible(true);
// 接著(zhù)打開(kāi)我們將使用的模板工作薄
ExcelWorkbooks xlBooks = excel.Workbooks();
ExcelWorkbook xlBook = xlBooks.Open("c:sales.xls");
// 接著(zhù)獲取我們將修改的范圍的引用
ExcelWorksheets xlSheets = xlBook.Worksheets();
ExcelWorksheet xlSheet = xlSheets.Item(1);
ExcelRange xlRange = xlSheet.Cells();
…
// 此處放置數據庫鏈接和查詢(xún)建立代碼
…
if (stmt.execute(strSql))
{
rs = stmt.getResultSet();
}
int nColCount = rs.getMetaData().getColumnCount();
int nRow=1;
int nCol=0;
// 在記錄集中循環(huán)
while(rs.next())
{
// 記錄集中的每行都是電子表格中的一行
nRow++;
for(int i=1;i<=nColCount;i++)
{
// 匹配DB列和電子表格列
nCol = getExcelColumn(i);
// 查找于行和列對應的單元格,并把它設置為適當的記錄集字段
xlRange.Item(nRow,nCol).Value(rs.getObject(i).toString());
}
// 填入公式
xlRange.Item(nRow,7).Value("=RC[-2]*RC[-1]");
xlRange.Item(nRow,9).Value("=RC[-2]*RC[-1]/100");
xlRange.Item(nRow,10).Value("=RC[-3]+RC[-1]");
xlRange.Item(nRow,11).Value("=RC[-4]*((100-RC[2])/100)");
}
在列表2的第一部分中,其目標是獲取希望修改的單元格的控制權。這會(huì )花費了一定的開(kāi)銷(xiāo)。
· 首先你必須獲取表現Excel本身的對象,有了JCOM輔助類(lèi)的幫助以后,這一步操作相當直接。
ExcelApplication excel = new ExcelApplication(rm);
· 下一步,你希望獲取對工作薄集合的訪(fǎng)問(wèn)權。你希望打開(kāi)自己的模板工作?。ū臼纠羞@個(gè)模板在C:sales.xls中),在工作薄集合中打開(kāi)它。
ExcelWorkbooks xlBooks = excel.Workbooks();
· 下一步,你希望打開(kāi)自己的工作薄并獲取該工作薄集合的引用。
ExcelWorkbook xlBook = xlBooks.Open("c:sales.xls");
ExcelWorksheets xlSheets = xlBook.Worksheets();
· 最后,你希望獲取集合中的第一個(gè)工作表,并把工作范圍定義為整個(gè)工作表。
ExcelWorksheet xlSheet = xlSheets.Item(1);
ExcelRange xlRange = xlSheet.Cells();
完成這些工作以后,你的xlRange對象將允許你在單元中放入值和公式了。通過(guò)在前面的記錄集(從提交給數據庫的SQL命令中返回的)中循環(huán),使用xlRange.Item(nRow,nCol).Value("whatever")語(yǔ)法,逐行逐列地把記錄集中的值插入到電子表格中(語(yǔ)法中的whatever來(lái)自于記錄集)。通過(guò)使用rs.getObject(i).toString可以得到當前行中I列的值。通過(guò)使用rs.movenext(),當前行一直向后移動(dòng),直到記錄集的末尾。
你在列表2中可能會(huì )注意到一個(gè)奇怪的函數調用:
nCol = getExcelColumn(i);
這是一個(gè)簡(jiǎn)單的輔助函數,它把記錄集中的列編號與Excel中存放數據的位置進(jìn)行匹配。例如,如果你再次查看上面的SQL語(yǔ)句,傭金費率將返回到第8列。在電子表格中,存放它的列是第13列。這個(gè)函數用于處理兩者之間的轉換。更復雜的應用程序可以使用Excel中的命名(named)范圍來(lái)匹配列,但是這超出了本文的范圍。
最后,應用程序把公式輸入適當的單元中。它是使用Excel的R1C1符號來(lái)實(shí)現的,因此相應的字符串是用于描述公式的。在Excel中,假設你希望把第1行中A列的值與B列的值相加,然后放到C列中,那么你就需要在C列中輸入公式"=A1+B1"。如果在第二行你也希望這樣操作,那么可以復制和粘貼這個(gè)公式,它會(huì )自動(dòng)地更新為"=A2+B2"。
從示例程序中得到這些值需要一些字符串操作,但是如果使用"R1C1"相關(guān)的轉換就非常直接了。在本文的例子中,你在C1中輸入公式的時(shí)候,不需要給出"=A1+B1"引用,而是給出"=RC[-2]+RC[-1]"引用,它的意思是把向前兩列的值與向前一列的值相加。
當你移動(dòng)了其它行的時(shí)候,這個(gè)公式的值不會(huì )發(fā)生改變,因此它使我們生成程序所需要的值非常簡(jiǎn)單了。這也是我用于計算總銷(xiāo)售額、銷(xiāo)售稅金、毛銷(xiāo)售額和純銷(xiāo)售額的方法,如下所示:
xlRange.Item(nRow,7).Value("=RC[-2]*RC[-1]");
xlRange.Item(nRow,9).Value("=RC[-2]*RC[-1]/100");
xlRange.Item(nRow,10).Value("=RC[-3]+RC[-1]");
xlRange.Item(nRow,11).Value("=RC[-4]*((100-RC[2])/100)");
運行這段代碼將得到圖3所示的電子表格。
圖3:公式:Excel顯示了數據庫查詢(xún)的輸出信息
請注意,這是一種比較好的工程學(xué)經(jīng)驗,即不要在應用程序中包含公式,因為公式可能隨時(shí)改變,而你肯定不希望在改變公式的時(shí)候就去改變自己的代碼。這種辦法使每個(gè)新數據行成為包含公式的已有數據行的副本。模板電子表格(sales.xls)包含了假數據,并在第二列中包含了公式(第一列包含了列標題)。因此,當你填充每行的時(shí)候,在你填入數據庫值的之前線(xiàn)復制這一行的內容。通過(guò)這種辦法,公式通過(guò)復制進(jìn)入了新數據行,并且你不需要在Java代碼中包含任何業(yè)務(wù)邏輯。
我們看一看salesReport2.java文件(也在下載內容中)中的內容,你可以發(fā)現,我們并沒(méi)有使用前面所說(shuō)的公式,而是在While循環(huán)頂部使用了下面的代碼:
if(nRow>1)
{
String strDest="A"+(nRow+1);
ExcelRange xlRange2Copy = xlSheet.Range("A2:M2");
xlRange2Copy.Copy(xlSheet.Range(strDest));
}
除了第一行之外(第一行不需要處理,這樣的信息已經(jīng)包含在sales.xls中了),這段代碼將處理A2到M2之間的單元,并把它們復制到nRow+1標識的數據行中(nRow是當前行的編號)。加上1的原因是計算了列標題(列標題在第一行)。
超越Excel
請記住JCOM是用于COM的而不僅僅是用于Excel的。你可以使用這種工具在Java中控制幾乎所有的COM對象。Excel是最常見(jiàn)的被控制對象,因為有很多很好的輔助類(lèi)可以讓它更簡(jiǎn)單,但是所有的COM組件都是可以使用的。因此控制其它的應用程序(例如Word和Powerpoint)也是直接的。
下面是使用Word的一個(gè)例子:
IDispatch wdApp = new IDispatch(rm, "Word.Application");
wdApp.put("Visible", new Boolean(true));
由于沒(méi)有用于Word的直接的輔助類(lèi),每個(gè)部分都必須通過(guò)使用IDispatch對象來(lái)實(shí)現(用于Excel的下層輔助類(lèi)也是這樣實(shí)現的)。上面的代碼將載入微軟Word副本,并通過(guò)wdApp對象使它可以自動(dòng)化操作。接著(zhù)你可以使用類(lèi)似"put"(設置屬性)或"method"(調用方法)等方法來(lái)使用Word。例如,上面的代碼把Visible屬性設置為true,使得該Word應用程序可視。
如果你一定要使用Windows,那么有大量的COM組件可以擴充你的視野,它的數量比Java目前提供的多很多。通過(guò)串行和并行口進(jìn)行硬件控制也可以在Java中實(shí)現了,而這僅僅是個(gè)開(kāi)始。在你的工具包中有了JCOM之后,就不受任何限制了。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站