需求:將軟件處理的結果保存為一個報告文檔,文檔中包含表格、圖片、文字,格式為word的.doc和.pdf。生成word是為了便于用戶編輯。
開發環境:qt4.8.4+vs2010
在qt的官網上對于pdf的操作介紹如下:http://qt-project.org/wiki/Handling_PDF 。即通過QPrinter類來創建pdf;還有通過第三方庫PoDoFo、Hummus。本文主要介紹的是用QPrinter類來創建pdf。
在qt的官網上對于word的操作介紹如下:http://qt-project.org/wiki/Handling_Microsoft_Word_file_format 。即通過Word本身COM組件的形式,Qt的ActiveX框架來實現;還有通過xml來實現。本文主要介紹Qt ActiveX和html格式生成word文檔。
下面舉例詳細說明pdf和word文檔的生成:
1.pdf的生成
pdf文檔里要求有表格、圖片、文字,參考博客:http://blog.sina.com.cn/s/blog_a6fb6cc90101gvnx.html。里面有介紹文字、圖片、表格分別是怎樣通過QPrinter類來實現的。但是遇到一個麻煩就是怎樣把這三種格式的東西放在一起而且排版好呢,用上述博客里的方法嘗試之后,最終確定使用第三種生成表格(html格式)的方式來得到:
?
QPrinter printer_text;
printer_text.setOutputFormat(QPrinter::PdfFormat);
printer_text.setOutputFileName(pdfname);//pdfname為要保存的pdf文件名QTextDocument text_document;
QString html = GeneratePicWord();//自定義的函數,用來生成html代碼text_document.setHtml(html);
text_document.print(&printer_text);
QTextBlock it = text_document.end();
GeneratePicWord()函數的內容大致如下:
QString html;
//文字部分
QDateTime current_date_time = QDateTime::currentDateTime();
QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd");
html += "<h2 align=\"center\">育種管理模塊</h2>";
html += "<h4 align=\"center\">" + current_date + "</h2><br>";
//圖片部分
html += "<img align=\"middle\" src = \"" + imagepath + "\" width=\"600\" height=\""+QString::number(showHeight) + "\"/><br>" ;
//表格部分
html += "<table align=\"center\" border=\"0.2\" cellspacing=\"0\" cellpadding=\"0\" style=\"width: 100%; height: 100%;\">";
html +="<tr>";
QString fieldname;
for ( int i = 0; i < fieldCount; ++i)
{
fieldname = fields[i].name();
html +="<td bgcolor=\"Silver\">" + fieldname + "</td>";
}
html +="</tr></table>";
?
2.word的生成
word的生成可以用QActiveX來實現。博客:http://www.360doc.com/content/14/0227/16/7918060_356177077.shtml里說的比較詳細了。首先新建一個模板文件Id.dot,在模板文件中事先“插入”-》“書簽”,如下圖所示:
?
書簽主要在表格的第一行前兩列,分別是code,ndvi。表格下面有兩個書簽,分別是pic,pic2。用代碼插入需要的文字和圖片:
QAxWidget *word = new QAxWidget("Word.Application",this, Qt::MSWindowsOwnDC);word->setProperty("Visible", true);//get all documentsQAxObject *documents = word->querySubObject("Documents");//build a tempetate with .dot filedocuments->dynamicCall("Add(QString)", QString::fromLocal8Bit("F:/Id.dot"));//get the current actived documentQAxObject *document = word->querySubObject("ActiveDocument");QString code = "code";QAxObject *bookmark_code = document->querySubObject("Bookmarks(QVariant)", "code");if ( !bookmark_code->isNull()){bookmark_code->dynamicCall("Select(void)");bookmark_code->querySubObject("Range")->setProperty("Text", "textg");}QAxObject *bookmark_ndvi = document->querySubObject("Bookmarks(QVariant)", "ndvi");if ( !bookmark_ndvi->isNull()){bookmark_ndvi->dynamicCall("Select(void)");bookmark_ndvi->querySubObject("Range")->setProperty("Text", "ndvi");}QAxObject *bookmark_ndvi2 = document->querySubObject("Bookmarks(QVariant)", "ndvi");if ( !bookmark_ndvi2->isNull()){bookmark_ndvi2->dynamicCall("Select(void)");bookmark_ndvi2->querySubObject("Range")->setProperty("Text", "ndvi2");}QAxObject *bookmark_pic = document->querySubObject("Bookmarks(QVariant)", "pic");if ( !bookmark_pic->isNull()){bookmark_pic->dynamicCall("Select(void)");QAxObject *shapes = document->querySubObject("InlineShapes");shapes->dynamicCall("AddPicture(Const QString&)", "F:\\CND.jpg");}document->dynamicCall("SaveAs (const QString&)", QString("F:/testword.doc"));document->dynamicCall("Close(boolean)", false);word->dynamicCall("Quit()");
只會插入到第一行已經預設好書簽的位置。對于有多條數據,還不知道怎樣動 態創建 書簽來插入數據。在網上找了些資料,未能很好的通過模板書簽的方式來解決這兩個問題。
那么想通過上面生成pdf時的html能不能直接保存為.doc文件呢?答案是能!而且節約了很多時間,只需一次生成固定格式的html,就可以保存為pdf和doc文件,多好的事情啊,為什么要用Qt ActiveX呢。
當然不能直接把生成pdf的文件名改成doc就行了,還需要做下面一個事情:
?
QString html;
html += "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:w=\"urn:schemas-microsoft-com:office:word\" xmlns=\"http://www.w3.org/TR/REC-html40\"><head><meta http-equiv=Content-Type content=\"text/html; charset=gb2312\" >"; //這句可加可不加。主要是因為我在word里把doc另存為html文件后,看到有這么個頭標簽,由此想到直接將html文檔保存為doc文件。
html =GeneratePicWord();//該函數同生產pdf文檔的一樣QFile outFile(docname);
outFile.open(QIODevice::WriteOnly | QIODevice::Append );
QTextStream ts(&outFile);
ts<<html<<endl;
主要在后面那4行,將html輸出到doc文件中去。
得到的結果如圖:
?