本篇要點(diǎn):
1、文件讀寫(xiě)的基本操作
2、字符串分割
3、POI生成Excel文件(.xlsx)
需求:
將csv格式的數(shù)據(jù)文件的內(nèi)容導(dǎo)入到表格中,生成xlsx格式的文件。
(這是個(gè)很簡(jiǎn)單的任務(wù),這里記錄一下,以便以后復(fù)用代碼。)
轉(zhuǎn)換前:
轉(zhuǎn)換后:
起因:
思路:
整體思路
1、按行讀取文件數(shù)據(jù),過(guò)濾掉不必要的行。
2、有效行進(jìn)行數(shù)據(jù)分割。
3、分割好的數(shù)據(jù)存入表格的單元格。
4、輸出生成xlsx文件。
用記事本打開(kāi)csv文件分析一下,發(fā)現(xiàn)需要解決的問(wèn)題主要有:
1、開(kāi)頭有多余代碼
2、有重復(fù)的標(biāo)題行,每行末尾有無(wú)效數(shù)據(jù)(,,,,)
讀取行的詳細(xì)思路
1、正則匹配“+”開(kāi)頭的行(稱(chēng)為“+”行)并計(jì)數(shù),只有讀取“+”行計(jì)數(shù)為1時(shí),置布爾值title_read為true,表示下一行可以讀取為標(biāo)題行。
2、當(dāng)“+”行計(jì)數(shù)>=1時(shí),讀取的非“+”行才是有效行,這樣就可以忽略開(kāi)頭代碼。
3、當(dāng)“+”行計(jì)數(shù)!=1時(shí),置title_read為false,表示之后不再讀取標(biāo)題行。無(wú)效標(biāo)題行的判斷條件為title_read為false時(shí)“+”行計(jì)數(shù)為基數(shù)(因?yàn)槊總€(gè)標(biāo)題行前后都有一行“+”行)。這樣就可以忽略掉多余標(biāo)題行。
4、進(jìn)行字符串切割后,不輸出第一個(gè)(第一個(gè)“|”前是空字符串)和最后一個(gè)切割數(shù)據(jù)(“,,,,,”無(wú)效數(shù)據(jù))。
完整代碼
因?yàn)檫@是個(gè)人筆記,就不細(xì)講每一步的實(shí)現(xiàn)了,代碼比較簡(jiǎn)單,細(xì)節(jié)見(jiàn)注釋。
package excelOP;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
public class ExcelOp {
public void trans(String file_in,String file_out//參數(shù)file_in,file_out分別為輸入文件路徑和輸出文件路徑
){
/*實(shí)例化輸入、輸出流*/
File f_in=new File(file_in);//輸入文件
FileInputStream ips=null;
InputStreamReader ipsr=null;
File f_out=new File(file_out);//輸出文件
FileOutputStream ops=null;
try {
ips=new FileInputStream(f_in);
ipsr=new InputStreamReader(ips);
ops=new FileOutputStream(f_out);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*創(chuàng)建excel表格文件并輸出*/
//創(chuàng)建工作薄
SXSSFWorkbook wb = new SXSSFWorkbook();
try {
//創(chuàng)建新的一頁(yè)
SXSSFSheet sheet = wb.createSheet("new sheet");
BufferedReader br=new BufferedReader(ipsr);
int count_title_framelines=0;
boolean title_read=false;
String valueString = null;
int count_line=0;//表格的有效行計(jì)數(shù)
while ((valueString=br.readLine())!=null){//循環(huán)處理每一行
if(valueString.matches("\\+.+")){//正則匹配標(biāo)題前后行“+”開(kāi)頭的行
count_title_framelines++;
if(count_title_framelines==1)title_read=true;
else title_read=false;
}
else{//非“+”開(kāi)頭的行
if(!(title_read==false&&count_title_framelines%2==1)//忽略重復(fù)標(biāo)題行
&&count_title_framelines>=1){//忽略開(kāi)頭代碼
//分解每一行有效行
String[] strs_cell=valueString.split("\\|");//用“|”切割每一行作為一個(gè)單元格數(shù)據(jù)
SXSSFRow row = sheet.createRow((short)count_line);
for(int i=1;i<strs_cell.length-1;++i){//循環(huán)每個(gè)切割得到的數(shù)據(jù),除了最后一個(gè)(,,,)和第一個(gè)(空)
//創(chuàng)建要顯示的內(nèi)容,創(chuàng)建一個(gè)單元格,第一個(gè)參數(shù)為列坐標(biāo),第二個(gè)參數(shù)為行坐標(biāo),第三個(gè)參數(shù)為內(nèi)容
row.createCell((short)i-1).setCellValue(strs_cell[i]);
System.out.println("正在導(dǎo)入第"+count_line+"行……");
}
count_line++;
}
}
}
//把創(chuàng)建的表格寫(xiě)入到輸出流中,并關(guān)閉輸出流
wb.write(ops);
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(wb!=null){
try {
wb.close();
System.out.println("寫(xiě)入表格完畢!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ips!=null){
try {
ips.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ops!=null){
try {
ops.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ExcelOp exop=new ExcelOp();
exop.trans("Ngap.csv", "test.xlsx");
}
}
參考:
POI操作Excel常用方法總結(jié)
注:這篇主要講的是用HSSF生成xls格式的文件(Excel2003版之前用的格式),生成xlsx用的是SXSSF,如上個(gè)部分的代碼。不過(guò)相應(yīng)的操作大同小異,把所有的“HSSF”改成“SXSSF”即可,相應(yīng)的包可以到Apache官網(wǎng)下載,給個(gè)鏈接:Apache POI - Download Release Artifacts