操作Excel
前面提过,使用QtAxContainer打开Excel,以及获取Excel的属性、页数、内容等,又跟Word、PowerPoint不一样。
打开Excel
对于Excel来说,打开的应用是"Excel.Application",Application中每个Excel文档叫做Workbook,而操作Workbook的列表理所当然,叫做Workbooks。
于是,从开头到能够操作一个具体的Excel文档,也需要经过三个“东西”:Excel.Application、Workbooks、Workbook。
即:
// 为演示方便,下述代码没有进行错误处理以及资源清理
QVariant
loadExcel (const QString &filename)
{
auto application = new QAxObject ("Excel.Application");
application->setProperty ("Visible", false);
auto books = application->querySubObject ("Workbooks");
auto book = books->querySubObject (
"Open(const QString&)", qname);
return book;
}
取得Excel工作表数
Excel的工作表列表,在Workbook里对应的名词叫做Sheets(Sheets里包含Chart与Worksheet两种子对象),可以取得Sheets的数量当成表的数量。
int
excelPageSum (QVariant book)
{
auto sheets = book->querySubObject ("Sheets");
auto count = sheets->property ("Count");
return count.toInt ();
}
取得Excel页面大小
Excel的Worksheet对象,有一个PageSetup子对象,但是这个对象并没有Width、Height属性,只有一个PagerSize属性,值为一个XlPaperSize。
XlPaperSize的官方文档页面 里说这是一系列可选值。
取得Excel行、列、单元格
Excel的Worksheet对象,有Rows、Columns表示行与列,另外还有Cells表示每一个单元格。
比如,下面代码可以清空指定的单元格的内容:
void
excelCellClear (QVariant book, int page_num, int cell_num){
auto sheets = book->querySubObject ("Sheets");
auto sheet = sheets->querySubObject ("Item(int)", page_num);
auto cells = sheet->querySubObject ("Cells");
auto cell = cells->querySubObject ("Item(int)", cell_num);
cell->dynamicCall ("ClearContents()");
}
Excel页面导出
要在Qt中显示Excel,最方便的办法是使用QAxWidget的setControl()方法,直接渲染一个QWidget出来显示在父QWidget里面。
否则,要把Excel导出成图片自己渲染,比较麻烦。
因为前面说过,Workbook的Sheets里面包含两种类型:Chart与Worksheet,Chart好导出,Worksheet不好导出。
Chart导出
Chart指的是Excel里面的图表,即柱状图、饼状图图等那些,Chart的Export方法,可以导出为图片。
Chart的Export的原型为:
Syntax
expression.Export (FileName, FilterName, Interactive)
expression A variable that represents a Chart object.
其中FileName是图片路径。
代码如下:
QImage
excelChartToImage (QVariant book, int page_num){
auto sheets = book->querySubObject ("Sheets");
auto chart = sheets->querySubObject ("Item(int)", page_num);
auto temppath
= QString ("%1/%2.png").arg (QDir::tempPath ()).arg (rand ());
temppath.replace ("/", "\\"); // 必须转化为\
sheet->dynamicCall ("Export(const QString &)", temppath);
if (QFile::exists (temppath) == false)
return QImage();
auto image = QImage (temppath);
QFile::remove (temppath);
return image;
}
Worksheet导出
但是,Worksheet就没有Export方法,只有ExportAsFixedFormat。
Worksheet的ExportAsFixedFormat原型为:
Syntax
expression.ExportAsFixedFormat (Type, FileName, Quality, IncludeDocProperties, IgnorePrintAreas, From, To, OpenAfterPublish, FixedFormatExtClassPtr)
expression A variable that represents a Worksheet object.
这其中,Type的类型为XlFixedFormatType,只有两个值:
0表示PDF,1表示XPS。
我们倒是可以使用Worksheet的这个方法,把给定页面转化成PDF,再使用Qt的QtPdf库,渲染单页面为图片,就是过程复杂了一些。
代码如下:
QImage
excelWorksheetToImage (QVariant book, int page_num){
auto sheets = book->querySubObject ("Sheets");
auto sheet = sheets->querySubObject ("Item(int)", page_num);
auto temppath
= QString ("%1/%2.pdf").arg (QDir::tempPath ()).arg (rand ());
temppath.replace ("/", "\\"); // 必须转化为\
sheet->dynamicCall ("ExportAsFixedFormat(int, const QString &)", 0, temppath); // 0表示PDF格式
if (QFile::exists (temppath) == false)
return QImage();
auto doc = QPdfDocument{};
doc.load (temppath);
auto size = doc.pagePointSize (0);
QSize image_size{ int (size.width ()), int (size.height ()) };
QPdfDocumentRenderOptions options{};
options.setRotation(QPdfDocumentRenderOptions::Rotation::None); options.setScaledSize (image_size);
auto image = doc.render (0, image_size, options);
QFile::remove (temppath);
return image;
}