首先你這個Excel文件是從哪裡來的,很可能是從一個頁面上下載來的,而這個頁面做的功能就是導出Excel,但做偷懶了,沒有用jxl和POI等庫,而是用直接用jsp生成html寫的。
因此你上傳時就要要判斷了,如果是真的excel就要用jxl或POI解析,如果只是html,就要用HTML的解析方法了。
2. java poi怎麼導入excel數據
package poi;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadExcel001 {
public static void main(String[] args) {
readXml("D:/test.xlsx");
System.out.println("-------------");
readXml("d:/test2.xls");
}
public static void readXml(String fileName){
boolean isE2007 = false; //判斷是否是excel2007格式
if(fileName.endsWith("xlsx"))
isE2007 = true;
try {
InputStream input = new FileInputStream(fileName); //建立輸入流
Workbook wb = null;
//根據文件格式(2003或者2007)來初始化
if(isE2007)
wb = new XSSFWorkbook(input);
else
wb = new HSSFWorkbook(input);
Sheet sheet = wb.getSheetAt(0); //獲得第一個表單
Iterator<Row> rows = sheet.rowIterator(); //獲得第一個表單的迭代器
while (rows.hasNext()) {
Row row = rows.next(); //獲得行數據
System.out.println("Row #" + row.getRowNum()); //獲得行號從0開始
Iterator<Cell> cells = row.cellIterator(); //獲得第一行的迭代器
while (cells.hasNext()) {
Cell cell = cells.next();
System.out.println("Cell #" + cell.getColumnIndex());
switch (cell.getCellType()) { //根據cell中的類型來輸出數據
case HSSFCell.CELL_TYPE_NUMERIC:
System.out.println(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
System.out.println(cell.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
System.out.println(cell.getCellFormula());
break;
default:
System.out.println("unsuported sell type");
break;
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
參考自http://blog.csdn.net/shuwei003/article/details/6741649
3. 如何用java poi編寫代碼來設置Excel單元格是否鎖定功能
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
/**
* @param inputFile 輸入模板文件路徑
* @param outputFile 輸入文件存放於伺服器路徑
* @param dataList 待導歲蘆出數據
* @throws Exception
* @roseuid:
*/
public void exportExcelFile(String inputFile, String outputFile, List dataList) throws Exception
{
/念前/用模板文件構造poi
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile));
//創建模板工作表
HSSFWorkbook templatewb = new HSSFWorkbook(fs);
//直接取模板第一個sheet對象
HSSFSheet templateSheet = templatewb.getSheetAt(1);
//得到模板的第一個sheet的第一行對象 為了得到模板樣式
HSSFRow templateRow = templateSheet.getRow(0);
//HSSFSheet timplateSheet = templatewb.getSheetAt(1);
//取得Excel文件的總列數
int columns = templateSheet.getRow((short) 0).getPhysicalNumberOfCells();
Debug.println("columns is : " + columns);
//創建樣式數組
HSSFCellStyle styleArray[] = new HSSFCellStyle[columns];
//一次性創建所有列的樣式放在數組里
for (int s = 0; s < columns; s++)
{
//得到數組實例
styleArray[s] = templatewb.createCellStyle();
}
//循乎高帶環對每一個單元格進行賦值
//定位行
for (int rowId = 1; rowId < dataList.size(); rowId++)
{
//依次取第rowId行數據 每一個數據是valueList
List valueList = (List) dataList.get(rowId - 1);
//定位列
for (int columnId = 0; columnId < columns; columnId++)
{
//依次取出對應與colunmId列的值
//每一個單元格的值
String dataValue = (String) valueList.get(columnId);
//取出colunmId列的的style
//模板每一列的樣式
HSSFCellStyle style = styleArray[columnId];
//取模板第colunmId列的單元格對象
//模板單元格對象
HSSFCell templateCell = templateRow.getCell((short) columnId);
//創建一個新的rowId行 行對象
//新建的行對象
HSSFRow hssfRow = templateSheet.createRow(rowId);
//創建新的rowId行 columnId列 單元格對象
//新建的單元格對象
HSSFCell cell = hssfRow.createCell((short) columnId);
//如果對應的模板單元格 樣式為非鎖定
if (templateCell.getCellStyle().getLocked() == false)
{
//設置此列style為非鎖定
style.setLocked(false);
//設置到新的單元格上
cell.setCellStyle(style);
}
//否則樣式為鎖定
else
{
//設置此列style為鎖定
style.setLocked(true);
//設置到新單元格上
cell.setCellStyle(style);
}
//設置編碼
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
//Debug.println("dataValue : " + dataValue);
//設置值 統一為String
cell.setCellValue(dataValue);
}
}
//設置輸入流
FileOutputStream fOut = new FileOutputStream(outputFile);
//將模板的內容寫到輸出文件上
templatewb.write(fOut);
fOut.flush();
//操作結束,關閉文件
fOut.close();
}
4. java poi 操作excel 問題
首先回答你第一個問題:
讀取註解代碼如下:
Comment comment = sheet.getRow(7).getCell(5, Row.CREATE_NULL_AS_BLANK).getCellComment();
根據批註定位單元格做不到。。。
5. java jxl怎麼讀取被密碼保護的excel
1.如果知道密碼怎麼讀取
現有的POI與JXL都沒有發現能夠讀取和加密的excel的功能。只能對文件進行加密。如果想讀取加密的excel,要藉助jxcell,下載地址http://www.jxcell.net
View m_view = new View();
m_view.read("E:\\pass.xls", "123456");
m_view.write("E:\\out.xls");
類似這樣輸出一個沒有密碼的文件,然後利用你熟悉的POI或JXL來操作,當然jxcell也可以。
從例子上看,jxcell支持2007
②如果不知道密碼怎麼讀取
這個沒有找到。我覺得這個也不應該屬於這些工具類的范圍。不知道密碼也想讀取,那是破解密碼了。
③該文件比較大,如果用POI的話,直接內存溢出,如果是用jxl的話,不會內存溢出,但是會出現文檔保密不準讀取
這個文件有多大,我試了一個5M的(這是我現在手頭上最大的文件了),沒有什麼問題。你那個是多大的?
6. java如何讀取一個加密後的.xls文件
近日來,研究了一下Excel Biff8(xls 97-2007)與OpenXML(ECMA-376)的加密文檔的讀取(這還是為了我們世界先進Grid而做的 ^__^)。有些成果,寫在這里,希望能給要做類似功能的XD們一些參考。
如有不詳,請聯系:[email protected] / [email protected]
前提:
1. 加密文檔:指Wookbook級的加密,就是在Save Excel文檔時在General Settings中設置open password之後的文檔;
2. 打開:需要用戶傳入密碼。並非破解。但請勿將本文方法添加暴力模塊使用 :-) ;
3. 本文涉及較多為,密鑰計算,關於解密細節請參考微軟相關文檔;
使用的加密演算法: RC4, SHA1, MD5, AES-128(其中RC4並不包含在所有版本的.NET Framework中,AES演算法可以在.NET Framework 3.5中找到)
本文示例依賴 .NET Framework 3.5
A. Biff8 的加密文檔讀取
1. 通過文檔中FILEPASS的record取得,文檔的加密信息(關於Biff文檔的格式問題,請參閱Biff的微軟文檔)
其中Biff8可以使用兩種方法加密:Biff8標准加密演算法和Biff8擴充加密演算法。本文主要討論最常用的Biff標准加密演算法
2. 通過FILEPASS的結構,獲得如下信息:
salt(加密隨機數,16 bytes)
password verifier (密碼效驗器,16 bytes)
password verifier hash(密碼效驗器Hash,16 bytes)
3. 通過以上信息,生成解密key。並通過密碼效驗器,驗證密碼:
i. 將密碼轉化成unicode數組,並進行MD5 Hash;
ii. 將hash結果與salt串聯,然後將byte數組,反復串聯16次(336 bytes) ,然後再進行MD5 Hash;
iii. 將上步hash結果的前五位,串聯上4 bytes的block值(在密碼驗證階段為0,在以後解密階段為block的index) ,然後進行MD5 Hash;
iv. 將上步hash結果的前16位,作為key
v. 使用RC4對稱加密演算法,將password verifier和password verifier hash分別解密,然後對password verifier的解密結果進行MD5 hash,其值應和password verifier hash的解密結果一致,即為密碼正確。
vi. 之後進行逐個record的解密。excel biff8加密原則基本為,record的標示不加密,長度不加密,個別record不加密(見文檔);另外,在record解密時,還需要通過block的值重新計算解密key,block的大小為1024.
4. 詳細請參照示例代碼;
B. OpenXML(ECMA-376) 加密文檔的讀取
1. 通常來說,xlsx文件相當於一個zip文件,可以用zip程序,直接打開。而在加密後,為了安全性考慮,微軟使用了 structured storage(一種OLE文檔存儲方式)存儲(可以用7-zip或者OLE document viewer打開,windows也有相應API來操作此類結構)。在上述文檔中,有一個叫做「EncryptedPackage」加密的package,就是一個zip包通過AES演算法進行加密之後的結果。我們將使用和A一樣的方式來檢查密碼,但生成key的方法不同;OpenXML的加密類型也有多種,我們這里就討論常用的用AES-128進行加密的流程;
2. 通過文檔的「EncryptedInfo」部分,需要過的一下信息(關於此部分的結構,請參考[MS-OFFCRYPTO].pdf)
salt(加密隨機數,16 bytes)
password verifier (密碼效驗器,16 bytes)
password verifier hash(密碼效驗器Hash,32 bytes)
3. 通過以上信息,生成解密key。並通過密碼效驗器,驗證密碼:
i. 首先,定義一個H函數,其有兩個輸入,內部使用SHA1演算法將兩個輸入串聯之後的結果hash返回;
ii. 先將salt與password(password的unicode數組)進行H計算,h = H(salt, password) ;
iii.然後設iterator為0x00000000,將其轉為4byte的數組,然後進行H計算,h1 = H(iterator, h);
iv.將上面的iterator遞增一,然後再與h1進行H計算,h2 = H(iterator,h1),然後將這個遞增和計算過程重復50000次,最後計算過的iterator為49999即可;
v. 現在有計算結果h50000,將h50000再與0x00000000(4 byte數組)進行H計算,Hfinal = H(h50000, 0x00000000);
vi. 生成一個64byte的數組,將每位都初始化成0x36,然後將這個數組與Hfinal異或;(關於這個地方,微軟文檔中寫的有錯誤,按照原文的方法生成的key不正確,要不是文檔的作者回信告訴我要使用這個法子,就算我想破頭也想不出來啊 T__T)
vii.將異或結果,進行SHA1 hash,結果的前16byte就是解密的key;
viii.初始化AES演算法,key長度為128,模式為ECB模式,Padding為none; 然後將password verifier 和password verifier hash分別解密;
ix. password verifier 解密後的SHA1 hash結果應該與password verifier hash解密後的前20byte相同;
4. 關於"EncryptedPackage" 的解密則更為簡單,只許將「EncryptedPackage」讀入,去除前8byte的size信息後,進行AES解密,即為未加密的標准openxml文檔。
參考:
[MS-OFFCRYPTO].pdf
[MS-XLS].pdf
ECMA-376 standards
Reply by "winnow", 2008-09-10, 1:17
-----------------------------------------------------
總結一下, 關於這兩種基於密碼的加密方法, 基本上都是基於RFC2898 建議, 思想是這樣:
輸入是用戶的密碼:password, 輸出是提供給加密函數的密鑰:key.
考慮安全, 需要使同樣的password生成的key不一樣, 這樣用相同的password加密後的結果就無法比較. 需要一個隨機數salt.
另外, 為了使暴力破解的代價增大, 考慮使用一個循環多次的過程, 需要循環次數:iteration_count.
概念上, 生成方法為: 將password和salt進行某種運算, 配合一個Hash函數, 以某種方式循環iteration_count次, 在最後的結果里取一部分作為key輸出.
具體參照RFC2898中的建議方法PBKDF1和PBKDF2.
這樣, 用戶輸入的密碼與一個隨機數組合, 經過一定代價的運算, 就生成了可以供加密函數使用的密鑰. 使用這個密鑰和一個加密函數, 就可以進行加密了.
在應用中, 為了快速判斷密碼是否錯誤. 生成一個隨機數verifier, 用一個Hash函數計算verifier的hash值:verifier_hash, 分別加密verifier和verifier_hash並保存.
解密的時候, 先分別解密出verifier和verifier_hash, 計算verifier的hash值, 與verifier_hash比較, 如果一致, 即說明密碼正確.
7. java POI 生成Excel 加密但不可以顯示只讀按鈕 可以嗎
打開Excel文件時顯示的,不是EXCEL文件格式問題,而是EXCEL軟體問題。
8. java使用poi解析或處理excel的時候,如何防止數字變成科學計數法的
思路為:為了防止數字變成科學計數法方式表示,在源文件以及java代碼中都用文本的方式去生成和解析excel,具體如下:
1.生成Excel時,設置單元格格式為STRING,即:
//關鍵代碼
HSSFCellcell=newHSSFCell();
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
2.同理,解析的時候,首先要保證源excel文件中該單元格格式是文本類型的,然後在java代碼里用STRING類型去解析:
//關鍵代碼
Stringvalue=cell.getStringCellValue();
9. java poi 寫excel文件的問題
最後的tableCell沒有指向後邊的幾個單元格啊。
10. JAVA POI操作EXCEL
循環insert語句,失敗的保存到數組中或者集合中,這樣每次芹巧開察首櫻敗叢關連接很消耗時間,然後一次性,用poi寫入excle中