您的位置:首页 > 编程语言 > Java开发

java转换文本文件到xlsx(自制缓冲区,无需先验文件行数)

2016-05-19 14:26 411 查看
【0】README
0.1)本文代码利用了 Apache POI 框架 建立 java 到 xlsx 代码的联系;
0.2)本文自制缓冲区从文本文件中读取数据读取,无需先验文件行数;
0.3)本文通过缓冲区大小创建数组,数组容量自动增加,该raw idea 来自于 tomcat 源码中在容器关联管道增加非基础阀的处理方式,包括Session池容量的增加也是这种处理方式;
0.4)for complete source code, please visit https://github.com/pacosonTang/postgraduate-research/tree/master/DataProcess

【1】如何自制缓冲区读取数据

step1)先建立一个缓冲大小确定(capacity)的二维数组指针data;
step2)通过循环读取数据,并填充二维数组;
step3)判断二维数组大小是否等于原定的缓冲大小(capacity);

step3.1)若等于:则增大缓冲区大小 为 newcapacity,并建立容量为 newcapacity 的二维数组指针datacopy,将原来的data数组的内容copy或填充到datacopy,并使得data指针的指向等于datacopy的指向;

step3.2)若不等于:继续下一步循环;

step4)循环完毕后,建立容量为 newcapacity 的二维数组指针datacopy,将原来的data数组的内容copy或填充到datacopy,并使得data指针的指向等于datacopy的指向;(bingo)

Attention)

A1)本文的capacity设定为10,你可以设定其他值,视具体情况而定;
A2)本文代码 在某些地方吧 data设置为null, 是为了便于 jvm 回收其内存;
// the core code begins.
int capacity=10; // buffer size, of course you can specify other values of capacity. step1
double[][] data = new double[capacity][];
int lineNum = 0;

while((str=reader.readLine())!=null) { // step2
String[] array = str.split(",");
double[] temp = new double[array.length-1];

for (int i = 0; i < array.length-1; i++) {
temp[i] = Double.valueOf(array[i]);
}
if(lineNum%capacity==0) {  // step3
double[][] datacopy = new double[lineNum+capacity][]; // step3.1
for (int i = 0; i < data.length; i++) {
datacopy[i] = data[i];
}
data = null;
data = datacopy;
}
data[lineNum++] = temp;	// step3.2
}
double[][] datacopy = new double[lineNum][]; // step4.
for (int i = 0; i < datacopy.length; i++) {
datacopy[i] = data[i];
}
data = null;
data = datacopy;
// the core code ends.<span style="font-family: SimSun; background-color: rgb(255, 255, 255);"> </span>


【2】intro to Apache POI
1)for downloading poi lib , please visit http://poi.apache.org/download.html,but
you can also download the libs of mine
Apache POI lib.
2)POI 将 xlsx 文件抽象为 Workbook对象,将xlsx文件中每张工作表抽象为 Sheet对象,代码如下:
public class XlsxDataModel
{
private Workbook workbook;
private Sheet sheet;
static XlsxDataModel model;

private XlsxDataModel(String sheetName){
this.workbook = new XSSFWorkbook();;
this.sheet = workbook.createSheet(sheetName);
}

public static XlsxDataModel getInstance(String sheetName){
if(model == null){
model = new XlsxDataModel(sheetName);
}
return model;
}

public Workbook getWorkbook() {
return workbook;
}

public Sheet getSheet() {
return sheet;
}
}

3)POI 将每一行抽象为Row对象,将每个单元格抽象为 Cell对象,这样就可以定位到每个单元格了,部分代码如下:
XlsxDataModel model = XlsxDataModel.getInstance(sheetName);
Row row = model.getSheet().createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("");

4)POI还从Sheet对象中抽象出遍历每行的迭代器,代码如下(从xlsx读取数据需要迭代器):
// 获取数据行 迭代器
final Iterator<Row> readIterator() {
Iterator<Row> itr = null;
try {
File excel = new File(this.dataPath);
FileInputStream fis = new FileInputStream(excel);
// 创建工作簿
XSSFWorkbook book = new XSSFWorkbook(fis);
// 创建工作簿下的第一页纸张
XSSFSheet sheet = book.getSheetAt(0);

// 纸张的迭代器,用于遍历行
itr = sheet.iterator();
// Iterating over Excel file in Java

} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return itr;
}

【3】将【1】中的idea 同 POI 结合起来
0)本文重点讲解写数据(写入到xlsx文件),读数据(从xlsx文件中读数据)只是po出方法而已;
1)目的:从文本文件中读取数据,并转化为xlsx文件格式;

step1)从文本读取数据;
step2)将存储文本数据的二维数组写入到xlsx;

public class DataProcess { // source code for step1 begins.
public static void main(String[] args) throws IOException {
String basedir = System.getProperty("user.dir") + File.separator;
BufferedReader reader =
new BufferedReader(new InputStreamReader(
new FileInputStream(basedir+"iris_data.txt")));
String str;

// the core code begins.
int capacity=10; // buffer size, of course you can specify other values of capacity.
double[][] data = new double[capacity][];
int lineNum = 0;

while((str=reader.readLine())!=null) {
String[] array = str.split(",");
double[] temp = new double[array.length-1];

for (int i = 0; i < array.length-1; i++) {
temp[i] = Double.valueOf(array[i]);
}
if(lineNum%capacity==0) {
double[][] datacopy = new double[lineNum+capacity][];
for (int i = 0; i < data.length; i++) {
datacopy[i] = data[i];
}
data = null;
data = datacopy;
}
data[lineNum++] = temp;
}
double[][] datacopy = new double[lineNum][];
for (int i = 0; i < datacopy.length; i++) {
datacopy[i] = data[i];
}
data = null;
data = datacopy;
// source code for step1 ends.

DataWrite writer = new DataWrite(basedir+"gmeans_irise1.xlsx");// source code for step2 begins.
writer.writeArray(data, "item", data[0].length, "iris"); // source code for step2 ends. highlight line.
}
}
/**
* @author Rong Tang
* @version 1.0
* @since 20150911
*/
public class DataWrite {
private String filepath;
private FileOutputStream out;

public DataWrite(String filepath) {
this.filepath = filepath;
}

/**
* @param data is a double array storing data written into xlsx.
* @param colPrefix is a row tag.
* @param headColNum is column number.
* @param sheetName is the name of sheet.
* @throws IOException
*/
public void writeArray(double[][] data, String colPrefix, int headColNum, String sheetName)
throws IOException {
XlsxDataModel model = XlsxDataModel.getInstance(sheetName); Row row = model.getSheet().createRow(0); Cell cell = row.createCell(0); cell.setCellValue("");

for (int i = 1; i <= headColNum; i++) {
cell = row.createCell(i);
cell.setCellValue(i);
} // build the head line over

for (int i = 0; i < data.length; i++) {
row = model.getSheet().createRow(i + 1);

cell = row.createCell(0);
cell.setCellValue(colPrefix + (i + 1));
for (int j = 0; j < data[i].length; j++) {
cell = row.createCell(j + 1);
cell.setCellValue(data[i][j]);
}
}// write the cluster result(centroid vector) into xlsx over

out = new FileOutputStream(filepath);
model.getWorkbook().write(out);
out.flush();
out.close();

System.out.println("write " + filepath + " over");
}

/**
* @param data is a int array storing data written into xlsx.
* @param colPrefix is a row tag.
* @param headColNum is column number.
* @param sheetName is the name of sheet.
* @throws IOException
*/
public void writeArray(int[][] data, String colPrefix, int headColNum, String sheetName)
throws IOException {
XlsxDataModel model = XlsxDataModel.getInstance(sheetName); Row row = model.getSheet().createRow(0); Cell cell = row.createCell(0); cell.setCellValue("");

for (int i = 1; i <= headColNum; i++) {
cell = row.createCell(i);
cell.setCellValue(i);
} // build the head line over

for (int i = 0; i < data.length; i++) {
row = model.getSheet().createRow(i + 1);

cell = row.createCell(0);
cell.setCellValue(colPrefix + (i + 1));
for (int j = 0; j < data[i].length; j++) {
cell = row.createCell(j + 1);
cell.setCellValue(data[i][j]);
}
}// write the cluster result(centroid vector) into xlsx over

out = new FileOutputStream(filepath);
model.getWorkbook().write(out);
out.flush();
out.close();

System.out.println("write " + filepath + " over");
}
}

2)本文象征性的po 出 读数据方法
/**
* @author Rong Tang
* @version 1.0
* @since 20150911
*/
public class DataRead {
private String dataPath;

public DataRead(String dataPath) {
this.dataPath = dataPath;
}

/**
*
* @param row_start is a startup row startup index for reading.
* @param col_start is a startup column index for reading.
* @param array is a double array storing the data read from some xlsx.
*/
public final void readDataToArray(int row_start, int col_start, double[][] array) {

Iterator<Row> itr = readIterator(); // 获得遍历行 的迭代器
Row row = null; // 行对象
int row_index = 0;// 行索引
int col_index = 0;// 列索引
int row_length = array.length; // 数据行数
int col_length = array[0].length; // 数据列数

// the first row is ommited for it stores column index
if (itr.hasNext()) {
itr.next();
}

// 定位行指针到 row_start
while(itr.hasNext()){
row_index++;
if(row_index == row_start) {
row_index = 0;
break;
}
itr.next();
}// 定位 over

// other rows stores time series data
while (itr.hasNext() && (row_index<row_length)) {
col_index = 0;
row = itr.next();
Iterator<Cell> cellIterator = row.cellIterator(); // 遍历每行单元格的迭代器

Cell cell = null;
// the first column is ommited for it stores row index
if(cellIterator.hasNext()) {
cellIterator.next();
}

// 定位列指针到 col_start
while(cellIterator.hasNext()) {
col_index++;
if(col_index == col_start) {
col_index = 0;
break;
}
cellIterator.next();
}// 定位 over

while (cellIterator.hasNext() && (col_index<col_length)) {
cell = cellIterator.next();
array[row_index][col_index++] = cell.getNumericCellValue();
}// 一行数据读取完毕

row_index++;
} // 数据行读取完毕
}

// read data from xlsx to array
public final void readDataToArray(int row_start, int row_end) {

Iterator<Row> itr = readIterator(); // 获得遍历行 的迭代器
Row row = null; // 行对象
int index = 0;// 行索引
int row_length = row_end-row_start+1; // 数据行数

// the first row is ommited for it stores column index
if (itr.hasNext()) {
row = itr.next();
}

// 定位行指针到 row_start
while(itr.hasNext()){
index++;
if(index == row_start) {
break;
}
row = itr.next();
}

index -= row_start;
// other rows stores time series data
while (itr.hasNext() && (index!=row_length)) {
int j = 0;
row = itr.next();
Iterator<Cell> cellIterator = row.cellIterator(); // 遍历每行单元格的迭代器

Cell cell = null;
// the first column is ommited for it stores row index
if(cellIterator.hasNext())
cell = cellIterator.next();

while (cellIterator.hasNext()) {
cell = cellIterator.next();
ClusterData.items[index][j++] = cell.getNumericCellValue();
}// 一行数据读取完毕

index++;
} // 数据行读取完毕
}

// 获取数据行 迭代器 final Iterator<Row> readIterator() { Iterator<Row> itr = null; try { File excel = new File(this.dataPath); FileInputStream fis = new FileInputStream(excel); // 创建工作簿 XSSFWorkbook book = new XSSFWorkbook(fis); // 创建工作簿下的第一页纸张 XSSFSheet sheet = book.getSheetAt(0); // 纸张的迭代器,用于遍历行 itr = sheet.iterator(); // Iterating over Excel file in Java } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return itr; }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: