2016-05-11 2 views
1

хорошо прямо к проблеме. У меня есть excel, который заполняет строки порядка 50k-60k. Я должен сделать этот контент excel загруженным в mysql, обычно я использую apache poi для прочитайте и загрузите его в mysql, но этот файл не может быть прочитан с помощью apache poi, потому что файл был LARGE. Может ли кто-нибудь мне посоветовать, как это сделать? Вот мой пример кода для загрузки контента в MySQL с помощью Apache POI (это работает для некоторых маленьких XLSX файлов, содержащихся в 1000-2000 строк)Java - XLSX parse & database export

public static void uploadCrossSellCorpCard(FileItem file, String dbtable) { 
    System.out.println("UploadUtil Running" + file.getFileName().toString()); 
    try { 
     for(int i = 0; i<=sheetx.getLastRowNum(); i++){ 
      row = sheetx.getRow(i); 

      try{ 
       int oc = (int) row.getCell(0).getNumericCellValue(); 
       if((String.valueOf(oc).matches("[A-Za-z0-9]{3}"))){ 
        String rm_name = row.getCell(1).getStringCellValue(); 
        String company = row.getCell(2).getStringCellValue(); 
        String product = row.getCell(3).getStringCellValue(); 
        String detail = row.getCell(4).getStringCellValue(); 
        String type = row.getCell(5).getStringCellValue(); 

        String sql = "INSERT INTO " + dbtable + " VALUES('" 
          + oc + "','" + rm_name + "','" + company + "','" 
          + product + "','" + detail + "','" + type + "')";   
        save(sql); 
        System.out.println("Import rows " + i); 
       } 
      } catch (IllegalStateException e) { 
       e.printStackTrace(); 
      } catch (NullPointerException e) { 
       System.out.println(e); 
      } 
     } 
     System.out.println("Success import xlsx to mysql table"); 
    } catch (NullPointerException e){ 
     System.out.println(e); 
     System.out.println("Select the file first before uploading"); 
    } 
} 

спасибо за заранее и извините за мой плохой английский :)

примечание: я использую спящего режима метод схемы загрузки ручки .. «сохранить (SQL)» звонит мой метод гибернации

+0

я не знаю, как решить эту проблему первенствовать (кроме экспортировать его в CSV и импорт этого), но для вставки следует использовать PreparedStatement с BatchUpdate - вы preparedStatement.addBatch() каждая строка затем PreparedStatement .clearBatch(); каждые несколько тысяч строк (это выводит данные из памяти в БД). Это бесконечно быстрее, чем отдельные вставки. – slipperyseal

+0

У меня нет проблем с вставкой .. его уже работает с спящим режимом, да и с PreparedStatement .. теперь моя проблема в том, что я хочу, чтобы загрузить большое, и не может быть прочитано при использовании apache poi, я уже увеличил свой java размер кучи, но все еще есть та же проблема. – Diastowo

+0

проверьте это. есть потоковый API ... http://stackoverflow.com/questions/11891851/how-to-load-a-large-xlsx-file-with-apache-poi – slipperyseal

ответ

0

Вы можете попробовать использовать Apache POI SAX - прочитать раздел ->XSSF и SAX (Event API) по адресу https://poi.apache.org/spreadsheet/how-to.html

Вы можете прочитать целую прелюдию с строками 60k или даже 100k строк так же, как чтение xml-файла. единственное, что вам нужно позаботиться, - это пустая ячейка, поскольку тег xml для пустой ячейки просто пропустит ячейку, но вам может понравиться обновить значение null в таблице db для ячейки, представляющей пустое значение.

Решение -> вы можете прочитать инструкцию каждой строки и инструкции по установке огня в цикле. и следить за пустой ячейкой, контролируя адрес ячейки, если происходит разрыв, тогда проверьте соответствующее имя столбца и соответственно обновите инструкцию insert с нулевым значением.

Надеюсь, это вам поможет. ниже пример кода read excel и сохраните его в ArrayList из ArrayList для табличного представления. Я печатаю сообщение в консоли - «начинается новая строка» перед началом чтения и печати строки. и номер ячейки каждого значения перед печатью самого значения ячейки.

Я не позаботился о разрыве ячеек для пустой ячейки, но вы можете закодировать ее, основываясь на поиске пробелов в ячейке, поскольку в моем случае у меня нет пустой ячейки. Ищите адрес соты в консоли, который поможет вам обнаружить любой пробел и обработать его по своему усмотрению.

Запустите этот код и отлично работает для меня. не забудьте добавить xmlbeans-2.3.0.jar другие, кроме банок, требуемых операциями импорта.

import java.io.InputStream; 
import java.util.ArrayList; 

import org.apache.commons.lang3.time.DurationFormatUtils; 
import org.apache.commons.lang3.time.StopWatch; 
import org.apache.poi.xssf.eventusermodel.XSSFReader; 
import org.apache.poi.xssf.model.SharedStringsTable; 
import org.apache.poi.xssf.usermodel.XSSFRichTextString; 
import org.apache.poi.openxml4j.opc.OPCPackage; 
import org.xml.sax.Attributes; 
import org.xml.sax.ContentHandler; 
import org.xml.sax.InputSource; 
import org.xml.sax.SAXException; 
import org.xml.sax.XMLReader; 
import org.xml.sax.helpers.DefaultHandler; 
import org.xml.sax.helpers.XMLReaderFactory; 

public class ExcelToStringArray implements Cloneable { 

    public static ArrayList<ArrayList<StringBuilder>> stringArrayToReturn = new ArrayList<ArrayList<StringBuilder>>(); 
    public static ArrayList<StringBuilder> retainedString; 
    public static Integer lineCounter = 0; 

    public ArrayList<ArrayList<StringBuilder>> GetSheetInStringArray(String PathtoFilename, String rId) 
      throws Exception { 
     ExcelToStringArray myParser = new ExcelToStringArray(); 
     myParser.processOneSheet(PathtoFilename, rId); 
     return stringArrayToReturn; 
    } 

    public void processOneSheet(String PathtoFilename, String rId) throws Exception { 
     OPCPackage pkg = OPCPackage.open(PathtoFilename); 
     XSSFReader r = new XSSFReader(pkg); 
     SharedStringsTable sst = r.getSharedStringsTable(); 

     XMLReader parser = fetchSheetParser(sst); 

     InputStream sheet = r.getSheet(rId); 
     InputSource sheetSource = new InputSource(sheet); 
     parser.parse(sheetSource); 
     sheet.close(); 
    } 

    public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException { 
     XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); 
     ContentHandler handler = new SheetHandler(sst); 
     parser.setContentHandler(handler); 
     return parser; 
    } 

    private class SheetHandler extends DefaultHandler { 
     private SharedStringsTable sst; 
     private String lastContents; 
     private boolean nextIsString; 

     private SheetHandler(SharedStringsTable sst) { 
      this.sst = sst; 
     } 

     public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { 

      if (name.equals("row")) { 
       retainedString = new ArrayList<StringBuilder>(); 

       if (retainedString.isEmpty()) { 
        stringArrayToReturn.add(retainedString); 
        retainedString.clear(); 
       } 

       System.out.println("New row begins"); 

       retainedString.add(new StringBuilder(lineCounter.toString())); 
       lineCounter++; 
      } 
      // c => cell 
      if (name.equals("c")) { 
       // Print the cell reference 
       System.out.print(attributes.getValue("r") + " - "); 

       // System.out.print(attributes.getValue("r") + " - "); 
       // Figure out if the value is an index in the SST 
       String cellType = attributes.getValue("t"); 
       if (cellType != null && cellType.equals("s")) { 
        nextIsString = true; 
       } else { 
        nextIsString = false; 
       } 
      } 
      // Clear contents cache 
      lastContents = ""; 
     } 

     public void endElement(String uri, String localName, String name) throws SAXException { 
      // Process the last contents as required. 
      // Do now, as characters() may be called more than once 
      if (nextIsString) { 
       int idx = Integer.parseInt(lastContents); 
       lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); 
       nextIsString = false; 
      } 

      // v => contents of a cell 
      // Output after we've seen the string contents 
      if (name.equals("v")) { 
       System.out.println(lastContents); 
       // value of cell what it string or number 
       retainedString.add(new StringBuilder(lastContents)); 
      } 
     } 

     public void characters(char[] ch, int start, int length) throws SAXException { 
      lastContents += new String(ch, start, length); 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     StopWatch watch = new StopWatch(); 
     watch.start(); 
     ExcelToStringArray generate = new ExcelToStringArray(); 
     // rID1 is first sheet in my workbook for rId2 for second sheet and so 
     // on. 
     generate.GetSheetInStringArray("D:\\Users\\NIA\\Desktop\\0000_MasterTestSuite.xlsx", "rId10"); 

     watch.stop(); 

     System.out.println(DurationFormatUtils.formatDurationWords(watch.getTime(), true, true)); 
     System.out.println("done"); 
     System.out.println(generate.stringArrayToReturn); 

    } 

} 
+0

да, пожалуйста, вы можете мне показать меня код?? Кстати, спасибо за ваше объяснение :) – Diastowo