⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compoundfile.java

📁 一个非常有用的操作MCRSOFT EXCEL文件的工具。可以用JAVA方便的新建
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
      {
        if (psnames[i].equalsIgnoreCase(STANDARD_PROPERTY_SETS[j]))
        {
          standard = true;
          ReadPropertyStorage rps = new ReadPropertyStorage(ps, null, i);
          readPropertySets.put(psnames[i], rps);
        }
      }

      if (!standard)
      {
        try
        {
          byte[] data = null;
          if (ps.size > 0 )
          {
            data = readCompoundFile.getStream(ps.name);
          }
          else
          {
            data = new byte[0];
          }
          ReadPropertyStorage rps = new ReadPropertyStorage(ps, data, i);
          readPropertySets.put(psnames[i], rps);
          additionalPropertySets.add(rps);

          if (data.length > SMALL_BLOCK_THRESHOLD)
          {
            int blocks = getBigBlocksRequired(data.length);
            blocksRequired += blocks;
          }
          else
          {
            int blocks = getSmallBlocksRequired(data.length);
            numSmallBlocks += blocks;
          }
        }
        catch (BiffException e)
        {
          logger.error(e);
          throw new CopyAdditionalPropertySetsException();
        }
      }
    }

    additionalPropertyBlocks = blocksRequired;
  }


  /**
   * Writes out the excel file in OLE compound file format
   * 
   * @exception IOException 
   */
  public void write() throws IOException
  {
    writeHeader();
    writeExcelData();
    writeDocumentSummaryData();
    writeSummaryData();
    writeAdditionalPropertySets();
    writeSmallBlockDepot();
    writeSmallBlockDepotChain();
    writeBigBlockDepot();
    writePropertySets();
    
    // Don't flush or close the stream - this is handled by the enclosing File
    // object
  }

  /**
   * Writes out any additional property sets
   */
  private void writeAdditionalPropertySets() throws IOException
  {
    if (additionalPropertySets == null)
    {
      return;
    }

    for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ;)
    {
      ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
      byte[] data = rps.data;

      if (data.length > SMALL_BLOCK_THRESHOLD)
      {
        int numBlocks = getBigBlocksRequired(data.length);
        int requiredSize = numBlocks * BIG_BLOCK_SIZE;

        out.write(data, 0, data.length);
      
        byte[] padding = new byte[requiredSize - data.length];
        out.write(padding, 0, padding.length);
      }
    }

    //      if (rps.propertyStorage.name.equals("Module1"))
    /*
      {
        System.out.println("terminating");
        out.flush();
        out.close();
        System.exit(1);
      }
    */
  }

  /**
   * Writes out the excel data, padding it out with empty bytes as
   * necessary
   * Also write out empty 
   * 
   * @exception IOException 
   */
  private void writeExcelData() throws IOException
  {
    out.write(excelData, 0, size);

    byte[] padding = new byte[requiredSize - size];
    out.write(padding);
  }

  /**
   * Write out the document summary data.  This is just blank
   * 
   * @exception IOException 
   */
  private void writeDocumentSummaryData() throws IOException
  {
    byte[] padding = new byte[SMALL_BLOCK_THRESHOLD];

    // Write out the summary information
    out.write(padding);
  }

  /**
   * Write out the  summary data.  This is just blank
   * 
   * @exception IOException 
   */
  private void writeSummaryData() throws IOException
  {
    byte[] padding = new byte[SMALL_BLOCK_THRESHOLD];

    // Write out the summary information
    out.write(padding);
  }

  /**
   * Writes the compound file header
   * 
   * @exception IOException 
   */
  private void writeHeader() throws IOException
  {
    // Build up the header array
    byte[] headerBlock = new byte[BIG_BLOCK_SIZE];
    byte[] extensionBlockData = new byte[BIG_BLOCK_SIZE * numExtensionBlocks];

    // Copy in the identifier
    System.arraycopy(IDENTIFIER, 0, headerBlock, 0, IDENTIFIER.length);

    // Copy in some magic values - no idea what they mean
    headerBlock[0x18] = 0x3e;
    headerBlock[0x1a] = 0x3;
    headerBlock[0x1c] = (byte) 0xfe;
    headerBlock[0x1d] = (byte) 0xff;
    headerBlock[0x1e] = 0x9;
    headerBlock[0x20] = 0x6;
    headerBlock[0x39] = 0x10;

    // Set the number of BBD blocks
    IntegerHelper.getFourBytes(numBigBlockDepotBlocks, 
                               headerBlock, 
                               NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);  

    // Set the small block depot chain 
    IntegerHelper.getFourBytes(sbdStartBlockChain,
                               headerBlock,
                               SMALL_BLOCK_DEPOT_BLOCK_POS);

    // Set the number of blocks in the small block depot chain 
    IntegerHelper.getFourBytes(numSmallBlockDepotChainBlocks,
                               headerBlock,
                               NUM_SMALL_BLOCK_DEPOT_BLOCKS_POS);

    // Set the extension block 
    IntegerHelper.getFourBytes(extensionBlock,
                               headerBlock,
                               EXTENSION_BLOCK_POS);

    // Set the number of extension blocks to be the number of BBD blocks - 1
    IntegerHelper.getFourBytes(numExtensionBlocks,
                               headerBlock, 
                               NUM_EXTENSION_BLOCK_POS);
    
    // Set the root start block
    IntegerHelper.getFourBytes(rootStartBlock,
                               headerBlock,
                               ROOT_START_BLOCK_POS);

    // Set the block numbers for the BBD.  Set the BBD running 
    // after the excel data and summary information
    int pos = BIG_BLOCK_DEPOT_BLOCKS_POS;

    // See how many blocks fit into the header
    int blocksToWrite = Math.min(numBigBlockDepotBlocks, 
                                 (BIG_BLOCK_SIZE - 
                                  BIG_BLOCK_DEPOT_BLOCKS_POS)/4);
    int extensionBlock = 0;
    int blocksWritten = 0;

    for (int i = 0 ; i < blocksToWrite; i++)
    {
      IntegerHelper.getFourBytes(bbdStartBlock + i, 
                                 headerBlock,
                                 pos);
      pos += 4;
      blocksWritten++;
    }
    
    // Pad out the rest of the header with blanks
    for (int i = pos; i < BIG_BLOCK_SIZE; i++)
    {
      headerBlock[i] = (byte) 0xff;
    }

    out.write(headerBlock);

    // Write out the extension blocks
    pos = 0;

    for (int extBlock = 0; extBlock < numExtensionBlocks; extBlock++)
    {
      blocksToWrite = Math.min(numBigBlockDepotBlocks - blocksWritten, 
                               BIG_BLOCK_SIZE/4 -1);

      for(int j = 0 ; j < blocksToWrite; j++)
      {
        IntegerHelper.getFourBytes(bbdStartBlock + blocksWritten + j, 
                                   extensionBlockData,
                                   pos);
        pos += 4;
      }

      blocksWritten += blocksToWrite;

      // Indicate the next block, or the termination of the chain
      int nextBlock = (blocksWritten == numBigBlockDepotBlocks) ? 
                              -2 : extBlock+1 ;
      IntegerHelper.getFourBytes(nextBlock, extensionBlockData, pos);
      pos +=4;
    }

    if (numExtensionBlocks > 0)
    {
      // Pad out the rest of the extension block with blanks
      for (int i = pos; i < extensionBlockData.length; i++)
      {
        extensionBlockData[i] = (byte) 0xff;
      }

      out.write(extensionBlockData);
    }
  }

  /**
   * Checks that the data can fit into the current BBD block.  If not,
   * then it moves on to the next block
   * 
   * @exception IOException 
   */
  private void checkBbdPos() throws IOException
  {
    if (bbdPos >= BIG_BLOCK_SIZE)
    {
      // Write out the extension block.  This will simply be the next block
      out.write(bigBlockDepot);
      
      // Create a new block
      bigBlockDepot = new byte[BIG_BLOCK_SIZE];
      bbdPos = 0;
    }
  }

  /**
   * Writes out the big block chain
   *
   * @param startBlock the starting block of the big block chain
   * @param numBlocks the number of blocks in the chain
   * @exception IOException
   */
  private void writeBlockChain(int startBlock, int numBlocks) 
    throws IOException
  {
    int blocksToWrite = numBlocks - 1;
    int blockNumber   = startBlock + 1;
    
    while (blocksToWrite > 0)
    {
      int bbdBlocks = Math.min(blocksToWrite, (BIG_BLOCK_SIZE - bbdPos)/4);

      for (int i = 0 ; i < bbdBlocks; i++)
      {
        IntegerHelper.getFourBytes(blockNumber, bigBlockDepot, bbdPos);
        bbdPos +=4 ;
        blockNumber++;
      }
      
      blocksToWrite -= bbdBlocks;
      checkBbdPos();
    }

    // Write the end of the block chain 
    IntegerHelper.getFourBytes(-2, bigBlockDepot, bbdPos);
    bbdPos += 4;
    checkBbdPos();
  }

  /**
   * Writes the block chains for the additional property sets
   *
   * @exception IOException
   */
  private void writeAdditionalPropertySetBlockChains() throws IOException
  {
    if (additionalPropertySets == null)
    {
      return;
    }

    int blockNumber = excelDataStartBlock + excelDataBlocks + 16;
    for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ; )
    {
      ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
      if (rps.data.length > SMALL_BLOCK_THRESHOLD)
      {
        String psname = rps.propertyStorage.name;
        int numBlocks = getBigBlocksRequired(rps.data.length);

        writeBlockChain(blockNumber, numBlocks);
        blockNumber += numBlocks;
      }
    }
  }
  
  /**
   * Writes out the chains for the small block depot
   */
  private void writeSmallBlockDepotChain() throws IOException
  {
    if (sbdStartBlockChain == -2)
    {
      return;
    }

    byte[] smallBlockDepotChain = 
      new byte[numSmallBlockDepotChainBlocks * BIG_BLOCK_SIZE];

    int pos = 0;
    int sbdBlockNumber = 1;

    for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ; )
    {
      ReadPropertyStorage rps = (ReadPropertyStorage) i.next();

      if (rps.data.length <= SMALL_BLOCK_THRESHOLD &&
          rps.data.length != 0)
      {
        int numSmallBlocks = getSmallBlocksRequired(rps.data.length);
        for (int j = 0 ; j < numSmallBlocks - 1 ; j++)
        {
          IntegerHelper.getFourBytes(sbdBlockNumber, 
                                     smallBlockDepotChain, 
                                     pos);
          pos += 4;
          sbdBlockNumber++;
        }

        // Write out the end of chain
        IntegerHelper.getFourBytes(-2, smallBlockDepotChain, pos);
        pos += 4;
        sbdBlockNumber++;
      }
    }

    out.write(smallBlockDepotChain);
  }

  /**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -