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

📄 vmexcelexporter.cpp

📁 TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language inter
💻 CPP
字号:
#include "VMExcelExporter.h"

#include <string.h>


// Attach the writer to the specified file 
//
VMLittleEndianWriter::VMLittleEndianWriter( FILE* f )
{
  m_pFile = f;
}

// Destructor closes the file itself
//
VMLittleEndianWriter::~VMLittleEndianWriter()
{
  fclose( m_pFile );
}

// Write 1 byte in the output
//
void VMLittleEndianWriter::WriteChar( char v )
{
  fwrite( &v, 1, 1, m_pFile );
}

// Write 2 bytes in the output (little endian order) 
//
void VMLittleEndianWriter::WriteInt( int v )
{
  WriteChar( ( v )      & 0xff );
  WriteChar( ( v >> 8 ) & 0xff );
}

// Write 4 bytes in the output (little endian order)
//
void VMLittleEndianWriter::WriteLong( long v )
{
  WriteInt( ( v )       & 0xffff );
  WriteInt( ( v >> 16 ) & 0xffff );
}

// Write a 4 byte float in the output
//
void VMLittleEndianWriter::WriteFloatIEEE( float v )
{
  fwrite( &v, 1, sizeof( v ), m_pFile );
}

// Write a 8 byte double in the output 
//
void VMLittleEndianWriter::WriteDoubleIEEE( double v )
{
  fwrite( &v, 1, sizeof( v ), m_pFile );
}

// Write a BIFF header for the opcode nRecno of length nRecLen 
//
void VMBaseBIFFRecord::Write( VMLittleEndianWriter* pWriter, int nRecNo, int nRecLen )
{
  pWriter->WriteInt( nRecNo  );
  pWriter->WriteInt( nRecLen );
}

// default constructor for our excel attributes 
//
VMExcelValueAttributes::VMExcelValueAttributes() 
{
  m_nRow   = m_nColumn = 0;
  m_nAttr1 = m_nAttr2  = m_nAttr3 = 0;
}

// set the row/column of these values 
//
VMExcelValueAttributes::VMExcelValueAttributes( int nRow, int nColumn )
{
  m_nRow    = nRow;
  m_nColumn = nColumn;
  m_nAttr1  = m_nAttr2 = m_nAttr3 = 0;
}

// write them to this endian writer 
//
void VMExcelValueAttributes::Write( VMLittleEndianWriter* pWriter )
{
  pWriter->WriteInt( m_nRow    );
  pWriter->WriteInt( m_nColumn );
  pWriter->WriteChar( m_nAttr1 );
  pWriter->WriteChar( m_nAttr2 );
  pWriter->WriteChar( m_nAttr3 );
}

int VMExcelValueAttributes::getRow()
{
  return m_nRow;
}

void VMExcelValueAttributes::setRow( int v )
{
  m_nRow = v;
}


int VMExcelValueAttributes::getColumn()
{
  return m_nColumn;
}

void VMExcelValueAttributes::setColumn( int v )
{
  m_nColumn = v;
}

void VMExcelValueAttributes::setHidden( bool v )
{
  if ( v ) 
  {
    m_nAttr1 |= 0x80;
  } 
  else 
  {
    m_nAttr1 &= ~0x80;
  }
}

bool VMExcelValueAttributes::getHidden()
{
  return ( m_nAttr1 & 0x80 ) != 0;
}

void VMExcelValueAttributes::setLocked( bool v )
{
  if ( v ) 
  {
    m_nAttr1 |= 0x40;
  } 
  else 
  {
    m_nAttr1 &= ~0x40;
  }
}

bool VMExcelValueAttributes::getLocked()
{
  return ( m_nAttr1 & 0x40 ) != 0;
}

void VMExcelValueAttributes::setShaded( bool v )
{
  if ( v ) 
  {
    m_nAttr3 |= 0x80;
  } 
  else 
  {
    m_nAttr3 &= ~0x80;
  }
}

bool VMExcelValueAttributes::getShaded()
{
  return ( m_nAttr3 & 0x80 ) != 0;
}

void VMExcelValueAttributes::setBorder( int type )
{
  m_nAttr3 &= ~0x78;            // clear existing border 
  m_nAttr3 |= ( type & 0x78 );  // set the new border    
}

int VMExcelValueAttributes::getBorder()
{
  return m_nAttr3 & 0x78;
}

void VMExcelValueAttributes::setAlignament( int type )
{
  m_nAttr3 &= ~0x07;          // clear previous value 
  m_nAttr3 |= type & 0x07;
}

int VMExcelValueAttributes::getAlignament()
{
  return m_nAttr3 & 0x07;
}

void VMExcelValueAttributes::setFontNum( int v )
{
  m_nAttr2 &= ~0xE0;               // clear previous value 
  m_nAttr2 |= ( v & 0x03 ) << 5;   // set the new value value 
}

int VMExcelValueAttributes::getFontNum()
{
  return ( m_nAttr2 >> 5 ) & 0x03;
}

void VMExcelValueAttributes::setFormatNum( int v )
{
  m_nAttr2 &= ~0x3F;          // clear previous value 
  m_nAttr2 |= v & 0x3F;       // set the new value value 
}

int VMExcelValueAttributes::getFormatNum()
{
  return m_nAttr2 & 0x3F;
}

// write a BOF record 
//
void VMExcelBOF::Write( VMLittleEndianWriter* pWriter )
{
  VMBaseBIFFRecord::Write( pWriter, OPCODE_BOF, 4 );
  pWriter->WriteInt( m_nVersion );
  pWriter->WriteInt( m_nType    );
}

// write a number 
//
void VMExcelNUMBER::Write( VMLittleEndianWriter* pWriter )
{
  VMBaseBIFFRecord::Write( pWriter, OPCODE_NUMBER, 15 );
  VMExcelValueAttributes::Write( pWriter );
  pWriter->WriteDoubleIEEE( m_nValue );
}

// write a label
//
void VMExcelLABEL::Write( VMLittleEndianWriter* pWriter )
{
  VMBaseBIFFRecord::Write( pWriter, OPCODE_LABEL, 8 + strlen ( m_pchValue ) );
  VMExcelValueAttributes::Write( pWriter );
  pWriter->WriteChar( strlen( m_pchValue ) );
  for ( unsigned i = 0; i < strlen( m_pchValue ); i++ ) 
  {
    pWriter->WriteChar( m_pchValue[ i ] );
  }
}

void VMExcelEOF::Write( VMLittleEndianWriter* pWriter )
{
  VMBaseBIFFRecord::Write( pWriter, OPCODE_EOF, 0 );
}

VMExcelCellVariant::VMExcelCellVariant() 
{
  m_pchValue = NULL;
  m_nValue   = 0;
  m_nType    = TYPE_NONE;
}
  
VMExcelCellVariant::VMExcelCellVariant( const VMExcelCellVariant& v )
{    
  m_nType = v.m_nType;

  if ( m_nType == TYPE_STRING )
  {
    m_pchValue = strdup( v.m_pchValue );
  }
  else
  {
    m_pchValue = NULL;
  }

  m_nValue = v.m_nValue;

  CopyAttributes( v );
}

VMExcelCellVariant::~VMExcelCellVariant() 
{
  if ( m_pchValue != NULL ) 
  {
    free( m_pchValue );
  }
}

// Excell cell can contain a double value 
//
VMExcelCellVariant& VMExcelCellVariant::operator = ( double v ) 
{
  m_nType  = TYPE_NUMBER;
  m_nValue = v;

  return *this;
}

VMExcelCellVariant::operator double()
{
  return m_nValue;
}
  
// Excell cell can also contain a string
//
VMExcelCellVariant& VMExcelCellVariant::operator = ( const char* v ) 
{
  m_nType = TYPE_STRING;

  if ( m_pchValue != NULL ) 
  {
    free( m_pchValue );
  }

  m_pchValue = strdup( v );    /* FIXME: check for NULL */
  return *this;
}

VMExcelCellVariant::operator const char* ()
{
  return m_pchValue;
}

void VMExcelCellVariant::clear()
{
  if ( m_pchValue != NULL ) 
  {
    free( m_pchValue );
    m_pchValue = NULL;
  }
  m_nType = TYPE_NONE;
}
  
VMExcelCellVariant& VMExcelCellVariant::operator = ( const VMExcelCellVariant& v )
{
  if ( m_pchValue != NULL ) 
  {
    free( m_pchValue );     
    m_pchValue = NULL;
  }
  m_nType = v.m_nType;

  if ( m_nType == TYPE_STRING )
  {
    m_pchValue = strdup( v.m_pchValue );
  }

  m_nValue = v.m_nValue;
  CopyAttributes( v );

  return *this;
}

void VMExcelCellVariant::Write( VMLittleEndianWriter* pWriter )
{
  if ( m_nType == TYPE_NONE ) 
  {
      return;                   // Do nothing if no actual value
  }
  if ( m_nType == TYPE_NUMBER ) 
  {
    VMExcelNUMBER n( m_nValue );

    n.CopyAttributes( *this );
    n.Write( pWriter );
  } 
  else
  if ( m_nType == TYPE_STRING ) 
  {
    VMExcelLABEL n( m_pchValue );

    n.CopyAttributes( *this );
    n.Write( pWriter );
  }
}

VMExcelCellVariant & VMExcelExporter::operator () ( unsigned row, unsigned column ) 
{
  while ( m_vvTableValues.size () <= row ) 
  {
    std::vector < VMExcelCellVariant > v;
    m_vvTableValues.push_back( v );       // add any extra rows
  }

  while ( m_vvTableValues[ row ].size () <= column ) 
  {
    VMExcelCellVariant v;

    m_vvTableValues[ row ].push_back( v );  // add any extra columns
  }

  return m_vvTableValues[ row ][ column ];

}
  
VMExcelExporter::VMExcelExporter()
{
}
  
VMExcelExporter::~VMExcelExporter()
{
}

void VMExcelExporter::Write( FILE* dest )
{
  VMLittleEndianWriter writer( dest );

  VMExcelBOF biffBOF( EXCEL_VERSION, TYPE_WORKSHEET );
  VMExcelEOF biffEOF;
  unsigned   row;
  unsigned   column;

  biffBOF.Write( &writer );

  // first pass, gather all the numbers 
  //
  for ( row = 0; row < m_vvTableValues.size (); row++ ) 
  {
    for ( column = 0; column < m_vvTableValues[ row ].size (); column++ ) 
    {
      if ( m_vvTableValues[ row ][ column ].getType () == VMExcelCellVariant::TYPE_NUMBER ) 
      {
        m_vvTableValues[ row ][ column ].setRow( row );
        m_vvTableValues[ row ][ column ].setColumn( column );
        m_vvTableValues[ row ][ column ].Write( &writer );
      }
    }
  }

  // second pass for the strings 
  //
  for ( row = 0; row < m_vvTableValues.size (); row++ ) 
  {
    for ( column = 0; column < m_vvTableValues[ row ].size (); column++ ) 
    {
      if ( m_vvTableValues[ row ][ column ].getType () == VMExcelCellVariant::TYPE_STRING ) 
      {
        m_vvTableValues[ row ][ column ].setRow( row );
        m_vvTableValues[ row ][ column ].setColumn( column );
        m_vvTableValues[ row ][ column ].Write( &writer );
      }
    }
  }

  biffEOF.Write( &writer );
}

⌨️ 快捷键说明

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