public void testSheets() throws Exception { OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("SampleSS.xlsx")); XSSFReader r = new XSSFReader(pkg); byte[] data = new byte[4096]; // By r:id assertNotNull(r.getSheet("rId2")); int read = IOUtils.readFully(r.getSheet("rId2"), data); assertEquals(974, read); // All Iterator<InputStream> it = r.getSheetsData(); int count = 0; while (it.hasNext()) { count++; InputStream inp = it.next(); assertNotNull(inp); read = IOUtils.readFully(inp, data); inp.close(); assertTrue(read > 400); assertTrue(read < 1500); } assertEquals(3, count); }
private NPOIFSFileSystem(FileChannel channel, boolean closeChannelOnError) throws IOException { this(false); try { // Get the header ByteBuffer headerBuffer = ByteBuffer.allocate(POIFSConstants.SMALLER_BIG_BLOCK_SIZE); IOUtils.readFully(channel, headerBuffer); // Have the header processed _header = new HeaderBlock(headerBuffer); // Now process the various entries _data = new FileBackedDataSource(channel); readCoreContents(); } catch (IOException e) { if (closeChannelOnError) { channel.close(); } throw e; } catch (RuntimeException e) { // Comes from Iterators etc. // TODO Decide if we can handle these better whilst // still sticking to the iterator contract if (closeChannelOnError) { channel.close(); } throw e; } }
/** * Create a POIFSFileSystem from an <tt>InputStream</tt>. Normally the stream is read until EOF. * The stream is always closed. * * <p>Some streams are usable after reaching EOF (typically those that return <code>true</code> * for <tt>markSupported()</tt>). In the unlikely case that the caller has such a stream * <i>and</i> needs to use it after this constructor completes, a work around is to wrap the * stream in order to trap the <tt>close()</tt> call. A convenience method ( * <tt>createNonClosingInputStream()</tt>) has been provided for this purpose: * * <pre> * InputStream wrappedStream = POIFSFileSystem.createNonClosingInputStream(is); * HSSFWorkbook wb = new HSSFWorkbook(wrappedStream); * is.reset(); * doSomethingElse(is); * </pre> * * Note also the special case of <tt>ByteArrayInputStream</tt> for which the <tt>close()</tt> * method does nothing. * * <pre> * ByteArrayInputStream bais = ... * HSSFWorkbook wb = new HSSFWorkbook(bais); // calls bais.close() ! * bais.reset(); // no problem * doSomethingElse(bais); * </pre> * * @param stream the InputStream from which to read the data * @exception IOException on errors reading, or on invalid data */ public NPOIFSFileSystem(InputStream stream) throws IOException { this(false); ReadableByteChannel channel = null; boolean success = false; try { // Turn our InputStream into something NIO based channel = Channels.newChannel(stream); // Get the header ByteBuffer headerBuffer = ByteBuffer.allocate(POIFSConstants.SMALLER_BIG_BLOCK_SIZE); IOUtils.readFully(channel, headerBuffer); // Have the header processed _header = new HeaderBlock(headerBuffer); // Sanity check the block count BlockAllocationTableReader.sanityCheckBlockCount(_header.getBATCount()); // We need to buffer the whole file into memory when // working with an InputStream. // The max possible size is when each BAT block entry is used int maxSize = BATBlock.calculateMaximumSize(_header); ByteBuffer data = ByteBuffer.allocate(maxSize); // Copy in the header headerBuffer.position(0); data.put(headerBuffer); data.position(headerBuffer.capacity()); // Now read the rest of the stream IOUtils.readFully(channel, data); success = true; // Turn it into a DataSource _data = new ByteArrayBackedDataSource(data.array(), data.position()); } finally { // As per the constructor contract, always close the stream if (channel != null) channel.close(); closeInputStream(stream, success); } // Now process the various entries readCoreContents(); }
/** * Checks that the supplied InputStream (which MUST support mark and reset, or be a * PushbackInputStream) has a POIFS (OLE2) header at the start of it. If your InputStream does not * support mark / reset, then wrap it in a PushBackInputStream, then be sure to always use that, * and not the original! * * @param inp An InputStream which supports either mark/reset, or is a PushbackInputStream */ public static boolean hasPOIFSHeader(InputStream inp) throws IOException { // We want to peek at the first 8 bytes inp.mark(8); byte[] header = new byte[8]; IOUtils.readFully(inp, header); LongField signature = new LongField(HeaderBlockConstants._signature_offset, header); // Wind back those 8 bytes if (inp instanceof PushbackInputStream) { PushbackInputStream pin = (PushbackInputStream) inp; pin.unread(header); } else { inp.reset(); } // Did it match the signature? return (signature.get() == HeaderBlockConstants._signature); }