📄 vmexcelexporter.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 + -