/** * Constructor * * @param l the length of the data * @param os the output stream to write to * @param data the excel data * @param rcf the read compound */ public CompoundFile(ExcelDataOutput data, int l, Stream os, CSharpJExcel.Jxl.Read.Biff.CompoundFile rcf) : base() { size = l; excelData = data; readAdditionalPropertySets(rcf); numRootEntryBlocks = 1; numPropertySets = 4 + (additionalPropertySets != null ? additionalPropertySets.Count : 0); if (additionalPropertySets != null) { numSmallBlockDepotChainBlocks = getBigBlocksRequired(numSmallBlocks * 4); numSmallBlockDepotBlocks = getBigBlocksRequired (numSmallBlocks * SMALL_BLOCK_SIZE); numRootEntryBlocks += getBigBlocksRequired (additionalPropertySets.Count * PROPERTY_STORAGE_BLOCK_SIZE); } int blocks = getBigBlocksRequired(l); // First pad the data outStream so that it fits nicely into a whole number // of blocks if (l < SMALL_BLOCK_THRESHOLD) requiredSize = SMALL_BLOCK_THRESHOLD; else requiredSize = blocks * BIG_BLOCK_SIZE; outStream = os; // Do the calculations excelDataBlocks = requiredSize / BIG_BLOCK_SIZE; numBigBlockDepotBlocks = 1; int blockChainLength = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS) / 4; int startTotalBlocks = excelDataBlocks + 8 + // summary block 8 + // document information additionalPropertyBlocks + numSmallBlockDepotBlocks + numSmallBlockDepotChainBlocks + numRootEntryBlocks; int totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; // Calculate the number of BBD blocks needed to hold this info numBigBlockDepotBlocks = (int)Math.Ceiling((double)totalBlocks / (double)(BIG_BLOCK_SIZE / 4)); // Does this affect the total? totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; // And recalculate numBigBlockDepotBlocks = (int)Math.Ceiling((double)totalBlocks / (double)(BIG_BLOCK_SIZE / 4)); // Does this affect the total? totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; // See if the excel bbd chain can fit into the header block. // Remember to allow for the end of chain indicator if (numBigBlockDepotBlocks > blockChainLength - 1) { // Sod it - we need an extension block. We have to go through // the whole tiresome calculation again extensionBlock = 0; // Compute the number of extension blocks int bbdBlocksLeft = numBigBlockDepotBlocks - blockChainLength + 1; numExtensionBlocks = (int)Math.Ceiling((double)bbdBlocksLeft / (double)(BIG_BLOCK_SIZE / 4 - 1)); // Modify the total number of blocks required and recalculate the // the number of bbd blocks totalBlocks = startTotalBlocks + numExtensionBlocks + numBigBlockDepotBlocks; numBigBlockDepotBlocks = (int)Math.Ceiling((double)totalBlocks / (double)(BIG_BLOCK_SIZE / 4)); // The final total totalBlocks = startTotalBlocks + numExtensionBlocks + numBigBlockDepotBlocks; } else { extensionBlock = -2; numExtensionBlocks = 0; } // Set the excel data start block to be after the header (and // its extensions) excelDataStartBlock = numExtensionBlocks; // Set the start block of the small block depot sbdStartBlock = -2; if (additionalPropertySets != null && numSmallBlockDepotBlocks != 0) { sbdStartBlock = excelDataStartBlock + excelDataBlocks + additionalPropertyBlocks + 16; } // Set the sbd chain start block to be after the excel data and the // small block depot sbdStartBlockChain = -2; if (sbdStartBlock != -2) { sbdStartBlockChain = sbdStartBlock + numSmallBlockDepotBlocks; } // Set the bbd start block to be after all the excel data if (sbdStartBlockChain != -2) { bbdStartBlock = sbdStartBlockChain + numSmallBlockDepotChainBlocks; } else { bbdStartBlock = excelDataStartBlock + excelDataBlocks + additionalPropertyBlocks + 16; } // Set the root start block to be after all the big block depot blocks rootStartBlock = bbdStartBlock + numBigBlockDepotBlocks; if (totalBlocks != rootStartBlock + numRootEntryBlocks) { //logger.warn("Root start block and total blocks are inconsistent " + // " generated file may be corrupt"); //logger.warn("RootStartBlock " + rootStartBlock + " totalBlocks " + totalBlocks); } }
private void createDataOutput() { if (workbookSettings.getUseTemporaryFileDuringWrite()) { data = new FileDataOutput(workbookSettings.getTemporaryFileDuringWriteDirectory()); } else { initialFileSize = workbookSettings.getInitialFileSize(); arrayGrowSize = workbookSettings.getArrayGrowSize(); data = new MemoryDataOutput(initialFileSize, arrayGrowSize); } }
/** * Closes the file. In fact, this writes out all the excel data * to disk using a CompoundFile object, and then frees up all the memory * allocated to the workbook * * @exception IOException * @exception JxlWriteException * @param cs TRUE if this should close the stream, FALSE if the application * closes it */ public void close(bool cs) { CompoundFile cf = new CompoundFile(data, data.getPosition(), outputStream, readCompoundFile); cf.write(); outputStream.Flush(); data.close(); if (cs) { outputStream.Close(); } // Cleanup the memory a bit data = null; //if (!workbookSettings.getGCDisabled()) // System.gc(); }
private void createDataOutput() { if (workbookSettings.getUseTemporaryFileDuringWrite()) data = new FileDataOutput(workbookSettings.getTemporaryFileDuringWriteDirectory()); else { initialFileSize = workbookSettings.getInitialFileSize(); arrayGrowSize = workbookSettings.getArrayGrowSize(); data = new MemoryDataOutput(initialFileSize, arrayGrowSize); } }
/** * Closes the file. In fact, this writes out all the excel data * to disk using a CompoundFile object, and then frees up all the memory * allocated to the workbook * * @exception IOException * @exception JxlWriteException * @param cs TRUE if this should close the stream, FALSE if the application * closes it */ public void close(bool cs) { CompoundFile cf = new CompoundFile(data, data.getPosition(), outputStream, readCompoundFile); cf.write(); outputStream.Flush(); data.close(); if (cs) outputStream.Close(); // Cleanup the memory a bit data = null; //if (!workbookSettings.getGCDisabled()) // System.gc(); }
/** * Constructor * * @param l the length of the data * @param os the output stream to write to * @param data the excel data * @param rcf the read compound */ public CompoundFile(ExcelDataOutput data, int l, Stream os, CSharpJExcel.Jxl.Read.Biff.CompoundFile rcf) : base() { size = l; excelData = data; readAdditionalPropertySets(rcf); numRootEntryBlocks = 1; numPropertySets = 4 + (additionalPropertySets != null ? additionalPropertySets.Count : 0); if (additionalPropertySets != null) { numSmallBlockDepotChainBlocks = getBigBlocksRequired(numSmallBlocks * 4); numSmallBlockDepotBlocks = getBigBlocksRequired (numSmallBlocks * SMALL_BLOCK_SIZE); numRootEntryBlocks += getBigBlocksRequired (additionalPropertySets.Count * PROPERTY_STORAGE_BLOCK_SIZE); } int blocks = getBigBlocksRequired(l); // First pad the data outStream so that it fits nicely into a whole number // of blocks if (l < SMALL_BLOCK_THRESHOLD) { requiredSize = SMALL_BLOCK_THRESHOLD; } else { requiredSize = blocks * BIG_BLOCK_SIZE; } outStream = os; // Do the calculations excelDataBlocks = requiredSize / BIG_BLOCK_SIZE; numBigBlockDepotBlocks = 1; int blockChainLength = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS) / 4; int startTotalBlocks = excelDataBlocks + 8 + // summary block 8 + // document information additionalPropertyBlocks + numSmallBlockDepotBlocks + numSmallBlockDepotChainBlocks + numRootEntryBlocks; int totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; // Calculate the number of BBD blocks needed to hold this info numBigBlockDepotBlocks = (int)Math.Ceiling((double)totalBlocks / (double)(BIG_BLOCK_SIZE / 4)); // Does this affect the total? totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; // And recalculate numBigBlockDepotBlocks = (int)Math.Ceiling((double)totalBlocks / (double)(BIG_BLOCK_SIZE / 4)); // Does this affect the total? totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; // See if the excel bbd chain can fit into the header block. // Remember to allow for the end of chain indicator if (numBigBlockDepotBlocks > blockChainLength - 1) { // Sod it - we need an extension block. We have to go through // the whole tiresome calculation again extensionBlock = 0; // Compute the number of extension blocks int bbdBlocksLeft = numBigBlockDepotBlocks - blockChainLength + 1; numExtensionBlocks = (int)Math.Ceiling((double)bbdBlocksLeft / (double)(BIG_BLOCK_SIZE / 4 - 1)); // Modify the total number of blocks required and recalculate the // the number of bbd blocks totalBlocks = startTotalBlocks + numExtensionBlocks + numBigBlockDepotBlocks; numBigBlockDepotBlocks = (int)Math.Ceiling((double)totalBlocks / (double)(BIG_BLOCK_SIZE / 4)); // The final total totalBlocks = startTotalBlocks + numExtensionBlocks + numBigBlockDepotBlocks; } else { extensionBlock = -2; numExtensionBlocks = 0; } // Set the excel data start block to be after the header (and // its extensions) excelDataStartBlock = numExtensionBlocks; // Set the start block of the small block depot sbdStartBlock = -2; if (additionalPropertySets != null && numSmallBlockDepotBlocks != 0) { sbdStartBlock = excelDataStartBlock + excelDataBlocks + additionalPropertyBlocks + 16; } // Set the sbd chain start block to be after the excel data and the // small block depot sbdStartBlockChain = -2; if (sbdStartBlock != -2) { sbdStartBlockChain = sbdStartBlock + numSmallBlockDepotBlocks; } // Set the bbd start block to be after all the excel data if (sbdStartBlockChain != -2) { bbdStartBlock = sbdStartBlockChain + numSmallBlockDepotChainBlocks; } else { bbdStartBlock = excelDataStartBlock + excelDataBlocks + additionalPropertyBlocks + 16; } // Set the root start block to be after all the big block depot blocks rootStartBlock = bbdStartBlock + numBigBlockDepotBlocks; if (totalBlocks != rootStartBlock + numRootEntryBlocks) { //logger.warn("Root start block and total blocks are inconsistent " + // " generated file may be corrupt"); //logger.warn("RootStartBlock " + rootStartBlock + " totalBlocks " + totalBlocks); } }