简体   繁体   English

按列名查找单元格并更改数据类型

[英]Find cells by their column name and change data type

I've a simple method to read csv and convert it to Excel:我有一个简单的方法来读取 csv 并将其转换为 Excel:

public static void main(String[] args) throws Exception {

        CSVReader csvReader = new CSVReader(new FileReader("P:\\employees.csv"));
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
  
        SXSSFSheet sxssfSheet = sxssfWorkbook.createSheet("Sheet");

        String[] dataRow = null;
        int rowNum = 0;
        while ((dataRow = csvReader.readNext()) != null) {
            Row currentRow = sxssfSheet.createRow(rowNum);
            for (int i = 0; i < dataRow.length; i++) {
                String cellValue = dataRow[i];
                currentRow.createCell(i).setCellValue(cellValue);
            }
            rowNum++;
        }
        sxssfWorkbook.write(new FileOutputStream("P:\\employees.xlsx"));
    }

But there's a problem with cell data type.但是单元格数据类型有问题。 All my data now represents as text.我所有的数据现在都表示为文本。 I want to find columns by their name (for example age , paid_total ), not by index, and set numeric (float) data type for these columns.我想按名称(例如agepaid_total )而不是索引查找列,并为这些列设置数字(浮点)数据类型。 Something like this (sorry for sql-like style, for me it's a simplier to describe): WHEN columnName IN ('age', 'paid_total') SET allColumnType AS NUMERIC .像这样的东西(对不起,对于类似 sql 的风格,对我来说,描述起来更简单): WHEN columnName IN ('age', 'paid_total') SET allColumnType AS NUMERIC How can I do this?我怎样才能做到这一点? Or it's only possible with indexes?或者只有索引才有可能?

CSV files always are plain text files without data types. CSV 文件始终是没有数据类型的纯文本文件。 But if you exactly know which column should be which data type, then a type safe Excel sheet can be created.但是,如果您确切地知道哪一列应该是哪种数据类型,那么就可以创建一个类型安全的 Excel 工作表。 This can be achieved by column indes as well as by column header. To detect types by column header, those headers wolud must be into a separate data structure.这可以通过列索引以及列 header 来实现。要通过列 header 检测类型,这些标题必须放入单独的数据结构中。 But this will always be benefical.但这总是有益的。

Let's take the example employees.csv from here: https://gist.github.com/kevin336/acbb2271e66c10a5b73aacf82ca82784 .让我们以此处的示例employees.csv为例: https://gist.github.com/kevin336/acbb2271e66c10a5b73aacf82ca82784

Then following should work:然后以下应该工作:

import java.io.*;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.streaming.*;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;

import com.opencsv.CSVReader;

import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeFormatter;
import java.time.LocalDate;

class CreateExcelFromCSVDifferentDataTypes {
    
 public static void main(String[] args) throws Exception {

  try (
   SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(); FileOutputStream fileout = new FileOutputStream("./employees.xlsx");
   CSVReader csvReader = new CSVReader(new FileReader("./employees.csv"));
   ) {

   sxssfWorkbook.setCompressTempFiles(true);
   
   CellStyle dateStyle = sxssfWorkbook.createCellStyle();
   dateStyle.setDataFormat(sxssfWorkbook.getCreationHelper().createDataFormat().getFormat("dd-MMM-yy"));
   
   SXSSFSheet sxssfSheet = sxssfWorkbook.createSheet("Sheet");
   sxssfSheet.setRandomAccessWindowSize(100);
   
   String[] strHeaders = null;
   String[] dataRow = null;
   int rowNum = 0;
   while ((dataRow = csvReader.readNext()) != null) {
    if (rowNum == 0) strHeaders = dataRow;
    Row currentRow = sxssfSheet.createRow(rowNum);
    for (int i = 0; i < dataRow.length; i++) {
     String cellValue = dataRow[i];
     if (rowNum > 0 && "HIRE_DATE".equals(strHeaders[i])) {
      DateTimeFormatter formatter= new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("dd-MMM-yy").toFormatter(java.util.Locale.ENGLISH);
      LocalDate localDate = LocalDate.parse(cellValue, formatter);
      currentRow.createCell(i).setCellValue(localDate);
      currentRow.getCell(i).setCellStyle(dateStyle);
     } else if (rowNum > 0 &&  "SALARY".equals(strHeaders[i])) {
      double d = Double.valueOf(cellValue);
      currentRow.createCell(i).setCellValue(d);   
     } else {    
      currentRow.createCell(i).setCellValue(cellValue);
     }
    }
    rowNum++;
   }
   
   sxssfWorkbook.write(fileout);
   sxssfWorkbook.dispose(); 
  }
 }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM