Qt奇技淫巧之Excl复制文本面板粘贴操作

       为了实现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单元格的保存,以上代码在项目中基本满足需求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值