2016-03-28 36 views
1

私はエクセルファイルをアップロードすることで受け取った番号を格納しなければならない機能に取り組んでいます。これは、Springフレームワークの下でApacheのpoiライブラリを使用してJavaで書かれています(これは無関係です)。apache POIは数値としてテキスト列を読み込みます

私は(カラムがすでにTextに設定されていることに注意してください)をアップロードしようとしているファイル:

enter image description here

コードは以下の通りです:

// function accepts "MultipartFile inputFile" 
InputStream is = inputFile.getInputStream(); 
StreamingReader reader = StreamingReader.builder().rowCacheSize(100).bufferSize(4096).sheetIndex(0) 
         .read(is); 
for (Row row : reader) { 
    System.out.println("Reading next row."); 
    System.out.println("row[0] is of type " + row.getCell(0).getCellType()); 
    Cell cell = row.getCell(0); 
    String value = ""; 
    if (cell.getCellType() == Cell.CELL_TYPE_STRING) { 
     value = cell.getStringCellValue().replaceAll("[\\D]", ""); 
    } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { 
     value = NumberToTextConverter.toText(cell.getNumericCellValue()); 
    } 
    System.out.println("Value is " + value); 
} 

そして私は」出力が下がる:

Reading next row. 
row[0] is of type 0 // Which is equals to Cell.CELL_TYPE_NUMERIC 
Value is 166609647 

I ssueは、 '166609647'の代わりに '0166609647'と読み替える必要があるということです、これはxlsxファイルとして保存され、ファイルを再アップロードすると、これはxlsxファイルにのみ起こります。細胞型。何か案は?

  • 考えると答えhttps://stackoverflow.com/a/19401902/1131470は、私たちはシートをストリーミングしている時に取得CellオブジェクトがStreamingCell対象になるだろうとして、サポートされていないDataFormatterクラスを使用しています:重複としてマークされているため

    編集getCellStyle()関数を呼び出すと例外がスローされます。

2016年3月29日のよう

クラスStreamingCellがDataFormatterは、どのようなExcelのディスプレイをつかむために、現時点で入手可能な唯一のクラスですDataFormatterをサポートしていないようです。現在のソリューションは、Excelファイル全体をメモリに読み込むことに固執しています。将来誰かが回答を見つけた場合は、ここに回答を投稿してください。私は、現在の解決策が絶対にひどいものであることをとても感謝しています。そのライブラリのバージョンの問題を指摘したアクセルに

2016年3月31日のような特別な感謝は、0.2.12にストリーマのjarファイルを更新することで問題を解決します。ありがとう!

+0

私はそれがhttps://github.com/monitorjbl/excel-streaming-readerであるのかもしれないと思います。したがって、最新版を使用していることを確認してください。 –

+0

@AxelRichterありがとうございます。StreamingCellのクラスを見ていただきありがとうございます。https://github.com/monitorjbl/excel-streaming-reader/blob/master/src/main/java/com/monitorjbl /xlsx/impl/StreamingCell.javaでは、ほとんどの関数がUnsupportedExceptionをスローするようです。選択肢はありませんが、アップロードサイズを制限しながらファイル全体を読み返す必要があります。 –

+0

あなたの言うことは真実ではありません。セルが 'Text'でフォーマットされている場合、OpenXMLではセルの型は' t = "s" 'であり、セルの値は' sharedStrings.xml'を指しています。だから 'row.getCell(0).getCellType()'は0にすることはできませんし、値は166609647にすることはできません。これは、セルが 'Text'としてフォーマットされていない**場合にのみ可能です。次に、フォーマッタが必要になります。 –

答えて

2

ファイルをダウンロードしました。 xlsx-streamer-0.2.12.jarslf4j-api-1.7.20.jarslf4j-nop-1.7.20.jarをダウンロードし、クラスパスに配置しました。

import com.monitorjbl.xlsx.*; 
import org.apache.poi.ss.usermodel.*; 

import java.io.*; 

class StreamingReaderTest { 

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

    try (
    InputStream is = new FileInputStream(new File("/home/axel/Downloads/test_formatted_number.xlsx")); 
    StreamingReader reader = StreamingReader.builder() 
      .rowCacheSize(100) 
      .bufferSize(4096) 
      .sheetIndex(0) 
      .read(is); 
) { 
    for (Row row : reader) { 
    System.out.println("row[0] is of type " + row.getCell(0).getCellType()); 
    Cell cell = row.getCell(0); 
    String value = ""; 
    if (cell.getCellType() == Cell.CELL_TYPE_STRING) { 
     value = cell.getStringCellValue(); 
    } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { 
     value = "" + cell.getNumericCellValue(); 
    } 
    System.out.println("Value is " + value); 
    } 
    } 
} 
} 

は私与える:

次のコードを持つので、問題はない、ここで

enter image description here

私は、数値セルの値とDataFormatterを使用する場合:

import com.monitorjbl.xlsx.*; 
import org.apache.poi.ss.usermodel.*; 

import java.io.*; 

class StreamingReaderTest { 

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

    try (
    InputStream is = new FileInputStream(new File("/home/axel/Downloads/test_formatted_number.xlsx")); 
    StreamingReader reader = StreamingReader.builder() 
      .rowCacheSize(100) 
      .bufferSize(4096) 
      .sheetIndex(0) 
      .read(is); 
) { 
    for (Row row : reader) { 
    System.out.println("row[0] is of type " + row.getCell(0).getCellType()); 
    Cell cell = row.getCell(0); 
    String value = ""; 
    if (cell.getCellType() == Cell.CELL_TYPE_STRING) { 
     value = cell.getStringCellValue(); 
    } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { 
     value = new DataFormatter().formatCellValue(cell); 
    } 
    System.out.println("Value is " + value); 
    } 
    } 
} 
} 

0000000000としてフォーマットA2に番号166609647を置きます。その後、私が取得:

enter image description here

+0

うわー、絶対に素晴らしい、後であなたのストリーマjarファイルのバージョンでもう一度試してみましょう、それは私の問題を解決するだろうと期待.. –

+0

それは確かにバージョンの問題でした。私のプロジェクトでは、古いバージョンの0.2.3を使用していました。 –

0

なぜ .replaceAll( "[\ D]"、 "");

私のためにうまく動作し、ちょうど試しました。 問題が何であるかわかりました。

fis = new FileInputStream(inputFile); 
XSSFWorkbook inputWorkBook = new XSSFWorkbook (fis); 
XSSFSheet inputSheet = inputWorkBook.getSheetAt(0); 
Iterator<Row> rowIterator = inputSheet.iterator(); 

while(rowIterator.hasNext()) 
{ 
    Row row = rowIterator.next(); 
    Iterator<Cell> cellIterator = row.cellIterator(); 

    while (cellIterator.hasNext()) 
    { 
     Cell cell = cellIterator.next(); 

     switch (cell.getCellType()) 
     { 
      case Cell.CELL_TYPE_STRING: 
       System.out.print(cell.getStringCellValue() + "\t"); 
       break; 
      case Cell.CELL_TYPE_NUMERIC: 
       System.out.print(cell.getNumericCellValue() + "\t"); 
       break; 
      case Cell.CELL_TYPE_BOOLEAN: 
       System.out.print(cell.getBooleanCellValue() + "\t"); 
       break; 
      default : 
     } 
    } 
    System.out.println(""); 
} 
+0

ああ、奇妙なものを指摘してくれてありがとう=)しかし、とにかくそれは私の質問が尋ねるものに影響を与えないので、私はちょうどその時にそれを残すだろう.. –

+0

こんにちは、努力のおかげで、再び申し訳ありません問題についてはあまり明確ではない。私がXLSファイルを受け入れるならば、私はあなたと同様のアプローチを使ってファイルを処理したいと思います。私がそれを行うと、 '0166609647'が正しく表示されます。非常に大きなXLSXファイルを受け入れると問題が発生します。そのため、ファイル全体をメモリに読み込む代わりにストリーミングが優先され、問題が発生します。 –

+0

私は私の質問にストリーミングオブジェクトを宣言する方法の部分を追加しました。 –

関連する問題