为了实现Excl粘贴文本操作,除了采用第三方的库与Excl进行操作外,这里举例简单的复制文本操作的操作
经过多次文本复制粘贴操作,发现Excl的行是通过\t进行判断,列是通过\n进行操作,而单元格是通过特殊的符号进行区分,读者可以进行代码实验区分,话不多进行代码直接上代码
struct UnitData
{
int row;
int columt;
QString data;
};
class ItemUnit
{
public:
ItemUnit( BaseTable *t = NULL );
~ItemUnit()
{
qDeleteAll( _unitDatas );
_unitDatas.clear();
}
bool save();
//load from table
bool load( const BaseTable * );
//load from clipboard
bool load( const QString & );
typedef QList<UnitData *> UnitDatas;
private:
QString paramChars(const QString&);
UnitDatas _unitDatas;
BaseTable *_table;
};
bool ItemUnit::save()
{
QModelIndexList lts = _table->selectionModel()->selectedIndexes();
if ( lts.count() > 0 )
{
int rowCount = _table->model()->rowCount();
int columnCount = _table->model()->columnCount();
QModelIndex first = lts.first();
QModelIndex last = lts.last();
int row = first.row();
int column = first.column();
QHash<int, int> cascadingSectionIndex;
int index = column;
for ( int i = column; i < _table->horizontalHeader()->count(); ++i )
{
if ( !_table->horizontalHeader()->isSectionHidden( i ) )
cascadingSectionIndex.insert( index++, i );
}
foreach( const UnitData * d, _unitDatas )
{
UnitData tableUnit;
tableUnit.row = row + d->row;
tableUnit.columt = cascadingSectionIndex.value( column + d->columt, 0xFFFF );
tableUnit.data = d->data;
if ( tableUnit.columt > 0 && tableUnit.row < rowCount && tableUnit.columt < columnCount ) //最大限值
{
if ( lts.count() == 1 || ( tableUnit.row <= last.row() && tableUnit.columt <= last.column() ) ) //选中限制
{
if ( _table->unitValid( &tableUnit ) ) //合法限制
_table->model()->setData( first.sibling( tableUnit.row, tableUnit.columt ), tableUnit.data );
}
}
}
}
return true;
}
bool ItemUnit::load( const QString &text )
{
if ( text.isEmpty() )
return false;
QString srcText = text;
_unitDatas.clear();
int row = 0, column = 0;
QString chars;
int deep = 0;
int test = 1;
for ( int i = 0; i < srcText.count(); ++i )
{
QChar char_ = srcText.at( i );
if ( char_.unicode() == 9 ) //"\t"
{
UnitData *d = new UnitData;
d->row = row;
d->columt = column;
d->data = paramChars(chars);
_unitDatas << d;
chars.clear();
++column;
deep = 0;
}
else if ( deep == 0 && char_.unicode() == 10 ) //"\n"
{
UnitData *d = new UnitData;
d->row = row;
d->columt = column;
d->data = paramChars(chars);
_unitDatas << d;
chars.clear();
column = 0;
++row;
deep = 0;
}
else if ( char_.unicode() == 34 ) //"\""
{
deep += test;
test = -1 * test;
chars.append( char_ );
}
else
chars.append( char_ );
}
return true;
}
QString ItemUnit::paramChars(const QString &chars)
{
QString d;
bool result = (chars.count() > 2 && chars.at(0).unicode() == 34 && chars.at(chars.count()-1).unicode() == 34);
for(int i = 0;i<chars.count();++i){
QChar char_ = chars.at( i );
if( !result )
d.append(char_);
else{
if( i != 0 && i != chars.count() - 1 ) {
if( char_.unicode() == 34 && i < chars.count()-1 && chars.at(i+1).unicode() == 34 )
++i;
d.append(char_);
}
}
}
return d;
}
bool ItemUnit::load( const BaseTable *_table )
{
QModelIndexList lts = _table->selectionModel()->selectedIndexes();
if ( lts.count() < 0 )
return false;
QModelIndex &first = lts.first();
QMap<int, QList<UnitData *> > unitDatas_;
foreach( const QModelIndex & index, lts )
{
int row = index.row();
int column = index.column();
if ( _table->horizontalHeader()->isSectionHidden( column ) )
continue;
UnitData *d = new UnitData;
d->row = row - first.row();
d->columt = column - first.column();
d->data = index.data();
unitDatas_[d->row] << d;
}
QString buff;
QMap<int, QList<UnitData *> >::iterator ite = unitDatas_.begin();
while ( ite != unitDatas_.end() )
{
for(int i = 0;i<ite.value().count();++i)
{
const QString& txt = ite.value().at(i)->data;
bool contain = txt.contains( "\n" );
QString str;
for(int i = 0;i<txt.count();++i)
{
QChar char_ = txt.at(i);
if( char_.unicode() == 34 && contain )
str.append(char_);
str.append(char_);
}
if ( contain )
str = QString( "\"%1\"" ).arg( str );
buff.append( str);
if ( i != d0.count()-1 )
buff.append( "\t" );
}
buff.append( "\n" );
++ite;
}
QApplication::postEvent( ( QObject * )_table, new UnitEvent( buff ) );
return true;
}
通过ItemUnit进行save和load分别进行复制面板的保存及加载操作,这里的save,笔者用于QtableView单元格的保存,以上代码在项目中基本满足需求