2015-04-27 3 views
2

Редактировать: разрешено. Я обошел ibatis/ApachePOI, написав jdbc-коннектор в базе данных, получив blob и сбросив его в файл. Когда-нибудь, я хотел бы точно знать, почему это пришло в голову - но сегодня я счастлив, что это позади.Oracle Blob to XLS рабочий лист

Резюме: Я получаю Oracle blobs и используя Apache POI для восстановления двоичных файлов Excel для прохождения через SOAP-сервисный уровень. Клиент .Net записывает их в .xls-файлы просто отлично, но имеет поврежденные файлы при записи в каталог UNIX.

Деталь: У меня есть Excel blobs, хранящиеся в таблице оракулов. Эти капли записываются с использованием iBatis и вытаскиваются с использованием этой (усеченной) карты результатов.

<resultMap id="report" class="Report">  
    <result column="content" property ="content" typeHandler="BlobByteArrayTypeHandler"/> 

Отчеты excel создаются с использованием Apache.POI нашими службами Java. На данный момент наш клиент (.net) запрашивает службу для байтового массива, который записывается на компьютер без ошибок - просто сбрасывает байты в файл.

Эти отличные файлы в порядке.

Проблема, с которой я столкнулась, состоит в том, что у нас есть новое требование, чтобы мы записывали эти файлы в файловую систему UNIX для дальнейшей обработки.

Все попытки этого потерпели неудачу. Вот некоторые примеры кода:

private void writeReportDumpBytes(Report report) { 
    File file = new File("report.xls"); 
    FileOutputStream fileOutputStream; 
    try { 
     fileOutputStream = new FileOutputStream(file); 
     fileOutputStream.write(report.getContent()); 
     fileOutputStream.flush(); 
     fileOutputStream.close(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void writeReportWithEncoding(Report report, String encoding) { 
    File file = new File("Report.xls"); 
    FileOutputStream fileOutputStream; 
    try { 
     fileOutputStream = new FileOutputStream(file); 
     OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, encoding);   
     Writer out = new BufferedWriter(outputStreamWriter); 
     String reportBytes = new String(report.getContent()); 
     out.write(reportBytes.toCharArray()); 
     out.flush(); 
     out.close(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    }    
} 

public void writeReportHssfPoifileSystem(Report report) { 
    try { 
     InputStream byteStream = new ByteArrayInputStream(report.getContent()); 
     POIFSFileSystem fs = new POIFSFileSystem(byteStream); 
     HSSFWorkbook workbook = new HSSFWorkbook(fs);   
     FileOutputStream fileOut = new FileOutputStream("Report.xls"); 
     workbook.write(fileOut); 
     fileOut.flush(); 
     fileOut.close(); 
    } catch (IOException e) { 
     log.error(e.getMessage(), e); 
    } 
} 

private void writeReportApacheIO(Report report) { 
    File file = new File("Report.xls"); 
    try {   
     logReportBytes(report, "Apache IO");    
     FileUtils.writeByteArrayToFile(file, report.getContent()); 
    } catch (IOException e) { 
     log.error("Caught IOException", e); 
    }    
} 

Для того, чтобы диагностировать это, я попытался схватить каплю из Oracle, и сохранить его в файл. В исполняемом файле «bare-bones jar» я смог прочитать байты из этого файла и переписать его, используя вышеуказанные методы в нашем окне UNIX, - и все они работают.

Однако из нашего кода файлы excel повреждены или отсутствуют сведения заголовков из Apache.POI. Открытие поврежденных/плохих двоичных файлов в текстовом редакторе показывает повторяющийся шаблон из 64 байтов. Это не допустимый двоичный файл xls.

Что-то идет вбок. Blob является действительным двоичным кодом xls, и мы просто получаем байты (используя iBatis выше) и передаем их обратно через объект HSSFWorkbook и пытаемся написать с использованием методов, как я их показал.

/** 
* Return the byte array based on the workbook. 
* 
* @return 
* @throws IOException 
*/ 
public byte[] getContent() throws IOException 
{ 
    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    this.workBook.write(bos); 
    return bos.toByteArray(); 
} 

Специфическая ошибка я получаю при использовании Apache POI является:

java.io.IOException: block[ 0 ] already removed 
at org.apache.poi.poifs.storage.BlockListImpl.remove(BlockListImpl.java:97) 
at org.apache.poi.poifs.storage.BlockAllocationTableReader.fetchBlocks(BlockAllocationTableReader.java:190) 
at org.apache.poi.poifs.storage.BlockListImpl.fetchBlocks(BlockListImpl.java:130) 
at org.apache.poi.poifs.property.PropertyTable.<init>(PropertyTable.java:79) 
at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:171) 
+0

Файлы Excel - это двоичные данные. Вы, кажется, используете Writers и Encodings, которые должны использоваться только с обычным текстом. Использование их с двоичными данными ломает вещи! Что произойдет, если вы заархивируете всех писателей и просто работаете с байтами/потоками? – Gagravarr

+0

Мой первый пример использует FileOutputStream только для записи, очень похожую на рабочий код .Net, но не работает в Unix. – hoosierChessGeek

ответ

0

Я написал JDBC вызов непосредственно к БД, игнорируя всю нелепость Ibatis и апача пои. Работал отлично, используя различные методы записи на диск.

Смежные вопросы