整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          concat() mysql 多個字段拼接,讀完之后

          concat() mysql 多個字段拼接,讀完之后,大部分程序員收藏了...

          法:

          COUNT(DISTINCT expr ,[expr ...])

          函數(shù)使用說明:返回不同的非NULL 值數(shù)目。若找不到匹配的項,則COUNT(DISTINCT) 返回 0

          Mysql的查詢結(jié)果行字段拼接,可以用下面兩個函數(shù)實現(xiàn):

          1. concat函數(shù)

          mysql> select concat('1','2','3') from test ; 
          +---------------------+ 
          | concat('1','2','3') | 
          +---------------------+ 
          | 123 | 
          +---------------------+
          

          如果連接串中存在NULL,則返回結(jié)果為NULL:

          mysql> select concat('1','2',NULL,'3') from test ; 
          +--------------------------+ 
          | concat('1','2',NULL,'3') | 
          +--------------------------+ 
          | NULL | 
          +--------------------------+ 
          

          2. concat_ws函數(shù)

          concat(separator,str1,str2,...) 代表 concat with separator ,是concat()的特殊形式。第一個參數(shù)是其它參數(shù)的分隔符。分隔符的位置放在要連接的兩個字符串之間。分隔符可以是一個字符串,也可以是其它參數(shù)。

          mysql> select concat_ws(':','1','2','3') from test ; 
          +----------------------------+ 
          | concat_ws(':','1','2','3') | 
          +----------------------------+ 
          | 1:2:3 | 
          +----------------------------+
          

          分隔符為NULL,則返回結(jié)果為NULL:

          mysql> select concat_ws(NULL,'1','2','3') from test; 
          +-----------------------------+ 
          | concat_ws(NULL,'1','2','3') | 
          +-----------------------------+ 
          | NULL | 
          +-----------------------------+ 
          

          如果參數(shù)中存在NULL,則會被忽略:

          mysql> select concat_ws(':','1','2',NULL,NULL,NULL,'3') from test ; 
          +-------------------------------------------+ 
          | concat_ws(':','1','2',NULL,NULL,NULL,'3') | 
          +-------------------------------------------+ 
          | 1:2:3 | 
          +-------------------------------------------+
          

          可以對NULL進行判斷,并用其它值進行替換:

          mysql> select concat_ws(':','1','2',ifNULL(NULL,'0'),'3') from bank limit 1; 
          +---------------------------------------------+ 
          | concat_ws(':','1','2',ifNULL(NULL,'0'),'3') | 
          +---------------------------------------------+ 
          | 1:2:0:3 | 
          +---------------------------------------------+ 
          

          concat的SQL注入:

          select username,email,content from test_table where user_id=uid;
          

          上面的user_id是接收輸入的。

          concat函數(shù)本來是這樣用的SELECT CONCAT('My', 'S', 'QL');執(zhí)行結(jié)果是'MySQL'。也就是連接作用的。我們利用它來為我們服務(wù),

          uid=-1 union select username ,concat(password,sex,address,telephone),content from test_table where user_id=管理員id;
          

          這個語句實際查詢了六個字段,但是顯示的時候,把password,sex,address,telephone等字段合在一起,顯示在原本應(yīng)該顯示email的地方。

          關(guān)注

          感謝閱讀,如果這篇文章幫助了您,歡迎 點贊 ,收藏,關(guān)注,轉(zhuǎn)發(fā) 喲。您的幫助是我們前行的動力,我們會提供更多有價值的內(nèi)容給大家... 謝謝!

          格語法:

          注意:顏色使用格式有三種:rgb(x,x,x) #xxxxxx colorname

          <table width=""></table>指定表格的寬度大小(使用數(shù)字pixel或%)

          <table border=""></table>設(shè)定表格邊框大小(使用數(shù)字pixel)

          <table align=""></table>表格位置,置左,為默認值

          align屬性:left(左對齊表格,默認值)、right(右對齊表格)、center(居中對齊表格)

          <table bgcolor=""></table>設(shè)定表格的背景顏色

          <table cellpadding=""></table>指定內(nèi)容與網(wǎng)格線之間的間距(使用數(shù)字pixel或%)

          <table cellspacing=""></table>指定網(wǎng)格線與網(wǎng)格線之間的距離(使用數(shù)字pixel或%)

          <table border="1" cellspacing="0" cellpadding="0">

          通常表格, 這兩個參數(shù)都設(shè)置為 0 。

          <table rules="rows"></table>規(guī)定內(nèi)側(cè)邊框的哪個部分是可見的。(兼容性差)

          rules屬性:none 沒有線條。

          groups 位于行組和列組之間的線條。

          rows 位于行之間的線條。

          cols 位于列之間的線條。

          all 位于行和列之間的線條。


          <table summary="Monthly savings for the Flintstones family"></table>

          定義了表格內(nèi)容的摘要:

          表格結(jié)構(gòu):

          在使用表格進行布局時, 可以將表格劃分為頭部、主體和頁腳, 具體如下所示:

          <thead></thead>:用于定義表格的頭部, 必須位于<table></table>標(biāo)記中, 一般包含網(wǎng)頁的logo和導(dǎo)航等頭部信息。

          <tfoot></tfoot>:用于定義表格的頁腳, 位于<table></table>標(biāo)記中<thead></thead>標(biāo)記之后, 一般包含網(wǎng)頁底部的企業(yè)信息等。

          <tbody></tbody>:用于定義表格的主體, 位于<table></table>標(biāo)記中<tfoot></tfoot>標(biāo)記之后, 一般包含網(wǎng)頁中除頭部和底部之外的其他內(nèi)容。

          注意:在沒有<tbody></tbody>比較的情況下, 瀏覽器會自動添加<tbody></tbody>標(biāo)記。

          <table bordercolor=""></table>設(shè)定表格邊框的顏色

          <table cols=""></table>指定表格的欄數(shù)

          <table height=""></table>指定表格的高度大小(使用數(shù)字)

          <table background=""></table>背景圖片的URL=就是路徑網(wǎng)址(默認是repeat:水平和垂直方向重復(fù))

          <table bordercolordark=""></table>設(shè)定表格暗邊框的顏色

          <table bordercolorlight=""></table>設(shè)定表格亮邊框的顏色

          <tr align=""></tr> 定義表格行的內(nèi)容對齊方式。

          align屬性值:right、left、center、justify、char

          <tr bgcolor=""></tr> 規(guī)定表格行的背景顏色。

          <tr valign=""></tr> 規(guī)定表格行中內(nèi)容的垂直對齊方式。

          valign屬性值right、left、center、justify、char

          <td colspan=""></td>指定儲存格合并欄的欄數(shù)(使用數(shù)字)

          <td rowspan=""></td>指定儲存格合并列的列數(shù)(使用數(shù)字)

          <td align=""></td> 調(diào)整表格字段之左右對齊

          <td bgcolor=""></td> 設(shè)定表格字段之背景顏色

          <td colspan="" rowspan=""></td> 表格字段的合并

          <td valign=""></td> 調(diào)整表格字段之上下對齊

          <td width=""></td> 調(diào)整表格字段寬度

          <td nowrap="nowrap"></td> 規(guī)定表格單元格中的內(nèi)容不換行(注意只有一個值:nowrap)

          <caption></caption>為表格加上標(biāo)題

          <caption align="">設(shè)定表格標(biāo)題位置

          align屬性:left, center(默認值), right

          <th></th> 定義表頭(粗體居中)

          細表格邊框

          <table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="158" height="68">
          <tr>
          <td width="158" height="68"></td>
          </tr>
          </table>

          表格創(chuàng)建后瀏覽器會自動添加<tbody>標(biāo)簽

          閱讀本文大概需要 6 分鐘

          日常開發(fā)軟件可能會遇到這類小眾需求,導(dǎo)出數(shù)據(jù)到 Word、Excel 以及 PDF文件,如果你使用 C++ 編程語言,那么可以選擇的方案不是很多,恰好最近剛好有這部分需求,整理下這段時間踩過的坑,方便后人

          讀寫 Word

          日常開發(fā)的軟件使用最多的應(yīng)該是導(dǎo)出數(shù)據(jù)到 Word 文檔中,目前可以用的方案有這幾種

          沒有十全十美的方案,任何方案都存在優(yōu)點和缺點,下面來詳細看下這幾種方案的優(yōu)缺點以及適用場景

          XML 模板替換

          原理:事先編輯好一份 Word 模板,需要替換內(nèi)容的 地方預(yù)留好位置,然后使用特殊字段進行標(biāo)記,后面使用代碼進行全量替換即可完成

          優(yōu)點

          • 代碼量相對較少、導(dǎo)出速度快
          • 跨平臺,支持多個系統(tǒng),系統(tǒng)不安裝 office 也能導(dǎo)出;
          • 支持圖片以及固定格式導(dǎo)出;

          缺點

          • 導(dǎo)出格式固定,可擴展性不強,如果需求變化導(dǎo)出格式變了,那么模板也要跟著改變;
          • 一種格式對應(yīng)一份模板,如果導(dǎo)出格式較多,需要準(zhǔn)備的模板文件較多,這樣比較繁瑣;
          • 需要 Word 2003 以上版本;

          舉個栗子

          我們先編輯一份 Word 模板文檔,內(nèi)容大概如下所示:

          • 將該文檔另存為 Word XML 文檔 XML-Template.xml
          • 讀取文檔內(nèi)容進行變量替換
              QFile file("XML-Template.xml");
              if (!file.open(QIODevice::ReadOnly))
              {
                  qDebug() << "open xxml file fail. " << file.errorString();
                  return 0;
              }
              QByteArray baContent=file.readAll();
              file.close();
              QString strAllContent=QString::fromLocal8Bit(baContent);
          
              strAllContent.replace("$VALUE0", "1");
              strAllContent.replace("$VALUE1", QString::fromLocal8Bit("法外狂徒張三"));
              strAllContent.replace("$VALUE2", QString::fromLocal8Bit("考試不合格"));
              strAllContent.replace("$VALUE3", "2");
              strAllContent.replace("$VALUE4", QString::fromLocal8Bit("李四"));
              strAllContent.replace("$VALUE5", QString::fromLocal8Bit("合格"));
          
              QFile newFile("export.doc");
              if (!newFile.open(QIODevice::WriteOnly))
              {
                  qDebug() << "file open fail." << newFile.errorString();;
                  return 0;
              }
          
              newFile.write(strAllContent.toLocal8Bit());
              newFile.close();
          
          • 保存替換后的內(nèi)容,寫入文件

          可以看出來這種方式比較繁瑣,重點是編輯固定的模板格式,而且編輯好后保存成XML格式后還需要繼續(xù)調(diào)整,這種 XML 格式標(biāo)簽很多,不小心就修改錯了,導(dǎo)致導(dǎo)出的文檔打不開

          這種方式適合模板內(nèi)容不太復(fù)雜,內(nèi)容較少的情況下使用

          COM 組件方式

          原理:采用 Micro Soft公開的接口進行通訊,進行讀寫時會打開一個 `Word進程來交互

          COM 技術(shù)概述

          Qt 為我們提供了專門進行交互的類和接口,使用 Qt ActiveX框架就可以很好的完成交互工作

          優(yōu)點

          • 實現(xiàn)簡單,快速上手;

          缺點

          • 導(dǎo)出寫入速度慢,因為相當(dāng)于打開 word 文檔操作;
          • Windows平臺可用,其它平臺失效;
          • 需要程序運行的電腦安裝 office word,否則調(diào)用失敗

          舉個栗子

          使用時需要引入對應(yīng)的模塊,在 pro 文件引入模塊

          QT  *=axcontainer
          

          打開文檔寫入內(nèi)容

          QAxObject *pWordWidget=new(std::nothrow) QAxObject;
          
          bool bResult=pWordWidget->setControl("word.Application");
          
          if (!bResult)
          {
              return false;
          }
          
          // 設(shè)置是否顯示
          pWordWidget->setProperty("Visible", false);
          
          QAxObject *pAllDocuments=pWordWidget->querySubObject("Documents");
          
          if(nullptr==pAllDocuments)
          {
              return false;
          }
          
          // 新建一個空白文檔
          pAllDocuments->dynamicCall("Add (void)");
          
          // 獲取激活的文檔并使用
          QAxObject *pActiveDocument=pAllDocuments->querySubObject("ActiveDocument");
          if(nullptr==pActiveDocument)
          {
              return false;
          }
          
          // 插入字符串
          QAxObject *pSelectObj=pWordWidget->querySubObject("Selection");
          if (nullptr !=pSelectObj)
          {
              pSelectObj->dynamicCall("TypeText(const QString&)", "公眾號:devstone");
          }
          
          ……
          

          可以看出來使用起來不難,對于新手友好一點,很多寫入操作方法比較繁瑣,需要自己重新封裝一套接口

          • 這種方案比較適合那些排版比較復(fù)雜,圖片、文字、表格混排的場景下,而且內(nèi)容都是動態(tài)變化的,可以很好的實現(xiàn)定制化
          • 當(dāng)然了它的缺點也不少,也有一些坑,有時候莫名其妙會失敗,還有就是比如你電腦安裝的 Word 沒有激活,那么每次啟動會彈激活窗口
          • 還有就是這種方式要求所有的路徑必須是本地化的,比如 D:\Soft\test.png
          • 使用前最好讀取注冊表判斷當(dāng)前電腦是否安裝了 Office Word,如果沒有安裝,直接讀取操作肯定會崩潰

          這種方式同樣適用于寫入 Excel 文件,后面再說

          HTML 方式

          原理:這種方式得益于 Word支持 HTML格式導(dǎo)出渲染顯示,那么反向也可以支持,需要我們拼接 HTML格式內(nèi)容,然后寫入文件保存成 .doc格式

          優(yōu)點

          • 跨平臺,不僅限于 Windows平臺,代碼可擴展性比較好
          • 導(dǎo)出速度快、代碼可擴展;

          缺點

          • 字符串拼接 HTML 容易出錯,缺失標(biāo)簽導(dǎo)出后無法顯示;
          • 插入的圖片是本地圖片文件的鏈接,導(dǎo)出的 word文檔拷貝到其它電腦圖片無法顯示

          舉個栗子

          QString HTML2Word::getHtmlContent()
          {
              QString strHtml="";
              strHtml +="<html>";
              strHtml +="<head>";
              strHtml +="<title>測試生成word文檔</title>";
              strHtml +="<head>";
              strHtml +="<body style=\"bgcolor:yellow\">";
              strHtml +="<h1 style=\"background-color:red\">測試qt實現(xiàn)生成word文檔</h1>";
              strHtml +="<hr>";
              strHtml +="<p>這里是插入圖片<img src=\"D:\\title.jpg" alt=\"picture\" width=\"100\" height=\"100\"></p>";
              strHtml +="</hr>";
              strHtml +="</body>";
              strHtml +="</html>";
          
              return strHtml;
          }
          
          // 保存寫入文件
          QFile file("D:/htmp2Word.doc");
          if (!file.open(QIODevice::WriteOnly))
          {
              return false;
          }
          
          QTextStream out(&file);
          out << getHtmlContent();
          file.close();
          
          

          這種方式難點在于 HTML格式拼接,任何缺失字段都會導(dǎo)致導(dǎo)出失敗,適合小眾需求下導(dǎo)出

          圖片問題其實可以手動進行轉(zhuǎn)化,文檔導(dǎo)出成功后手動拷貝內(nèi)容到新的文檔,這樣圖片就真正插入到文檔中,文檔發(fā)送給別人也不會丟失圖片了

          還有一個坑就是:如果你使用 WPS 打開導(dǎo)出的文檔,默認顯示的是 web視圖,需要手動進行調(diào)整

          某些電腦分辨率變化也會導(dǎo)致生成的文檔中字體等產(chǎn)生變化

          第三方開源庫

          可以使用的第三方庫幾乎沒有,網(wǎng)絡(luò)上找到的有這么幾個

          • OpenOffice: 兼容性差,集成調(diào)用難度大
          • LibOffice: 太龐大,不容易集成
          • DuckX: 太小眾,只能簡單的使用
          • docx:小眾庫

          DuckX庫 docx庫

          在讀寫 Word這部分,C++ 基本沒有可以使用的第三方庫,不像其他語言Java、C#、Python有很多可以選擇,這個痛苦也只有 C++ 程序員能夠理解了吧

          所以怎么選擇還是看自己項目需求吧,沒有十全十美的方案


          上面說了這么多,都是導(dǎo)出生成 Wrod,那么下面來看看有那些方式可以讀取顯示 Word內(nèi)容

          這種需求應(yīng)該不會很多,而且顯示難度更大一些

          使用 COM組件方式,即采用 QAxWidget框架顯示 office 文檔內(nèi)容,本質(zhì)上就是在我們編寫的 Qt 界面上嵌入 office 的軟件,這種方式其實和直接打開 Word查看沒有啥區(qū)別,效果、性能上不如直接打開更好一些

          目前一般都會采用折中方案,把 Word 轉(zhuǎn)為 PDF 進行預(yù)覽加載顯示,我們知道 PDF 渲染庫比較多,生態(tài)相對來說要好一些,在選擇上就更廣泛些,如何使用后面部分有專門介紹 PDF章節(jié)

          讀寫 Excel

          目前有一個支持比較好的第三方庫可以使用,整體使用基本可以滿足日常使用

          QXlsx

          這款開源庫支持跨平臺,Linux、Windows、Mac、IOS、Android,使用方式支持動態(tài)庫調(diào)用和源碼直接集成,非常方便

          編譯支持 qmakecmake,可以根據(jù)你自己的項目直接集成編譯,讀寫速度非常快

          QXlsx::Document xlsx;
          
          // 設(shè)置一些樣式
          QXlsx::Format titleFormat;
          titleFormat.setBorderStyle(QXlsx::Format::BorderThin);  // 邊框樣式
          titleFormat.setRowHeight(1,1,30);   // 設(shè)置行高
          titleFormat.setHorizontalAlignment(QXlsx::Format::AlignHCenter);   // 設(shè)置對齊方式
          
          // 插入文本
          xlsx.write(1,1, "微信公眾號:devstone", titleFormat);
          
          // 合并單元格
          xlsx.mergeCells(QXlsx::CellRange(2,1,4,4), titleFormat);
          
          // 導(dǎo)出保存
          xlsx.saveAs("D:/xlsx_export.xlsx");
          
          // 添加工作表
          xlsx.addSheet("devstone");
          

          可以看到上手非常容易、各個函數(shù)命名也貼近 Qt Api,是一款非常良心的開源軟件

          PS:注意該軟件使用 MIT 許可協(xié)議,這樣對于很多個人或者公司來說非常良心,意味著你可以無償使用、修改該項目,但是必須在你項目中也添加同樣的 MIP許可

          上面也提到了,還可以使用 COM 組件的方式讀寫 Excel,不過有了這款開源庫基本就可以告別 COM組件方式了

          讀寫 PDF

          PDF相關(guān)開源庫挺多的,給了 C++ 程序員莫大的幫助,目前可用的主要有這些

          其中 mupdfpoppler 屬于功能強大但是很難編譯的那種,需要有扎實的三方庫編譯能力,否則面對 n 個依賴庫會無從下手

          不過可喜的是 Github 上有兩個開源庫可以供選擇

          qpdf 庫

          這個庫其實封裝了 pdf.js庫,使用 WebEngine來執(zhí)行 JavaScript進而加載文件

          項目地址

          • 直接從本地文件加載;
          • 支持從內(nèi)存數(shù)據(jù)直接加載渲染 PDF 內(nèi)容;

          這種方式對環(huán)境有特殊要求了,如果你的項目使用的 Qt 版本不支持 WebEngine,那么就無法使用

          qtpdf 庫

          這個庫是 Qt 官方親自操刀對第三方庫進行了封裝,暴露的 APIQt 類似,使用起來非常舒服

          Qt 官方

          代碼結(jié)構(gòu)以及使用 Demo

          小試牛刀

          關(guān)于如何使用,官方已經(jīng)給了我們非常詳細的步驟了,直接跟著下面幾步就 OK 了

          官方教程

          git clone git://code.qt.io/qt-labs/qtpdf
          cd qtpdf
          git submodule update --init --recursive
          qmake
          make
          cd examples/pdf/pdfviewer
          qmake
          make
          
          ./pdfviewer /path/to/my/file.pdf
          

          可以看到使用了谷歌開源的 pdfium 三方庫,編譯時需要單獨更新下載這個庫,因為某些原因可能你無法下載,不過好在有人在 GitHub上同步了這個倉庫的鏡像,有條件還是建議直接下載最新穩(wěn)定版的

          可正常訪問的倉庫地址:https://github.com/PDFium/PDFium

          相關(guān)類可以看這個文檔:https://developers.foxit.com/resources/pdf-sdk/c_api_reference_pdfium/modules.html

          最后還要注意項目開源協(xié)議:pdfium引擎開始來自于福昕,一個中國本土的軟件公司,Google與其合作最終進行了開源,目前采用的是 BSD 3-Clause 協(xié)議,這種協(xié)議允許開發(fā)者自由使用、修改源代碼,也可以修改后重新發(fā)布,允許閉源進行商業(yè)行為,不過需要你在發(fā)布的產(chǎn)品中包含原作者代碼中的 BSD 協(xié)議

          總結(jié)

          以上就是項目中常用的文檔處理方法總結(jié),當(dāng)然了肯定也還有其它方案可以實現(xiàn),畢竟條條大路通羅馬,如果你還要不錯的方案和建議歡迎留言

          PS: 以上方案和對應(yīng)的源碼編譯、使用例子會統(tǒng)一上傳到 GitHub對應(yīng)的倉庫,方便后人使用

          取之互聯(lián)網(wǎng)、回報互聯(lián)網(wǎng)

          原創(chuàng)不易,如果覺得對你有幫助,歡迎點贊、在看、轉(zhuǎn)發(fā)

          推薦閱讀

          • Qt Creator 源碼學(xué)習(xí)筆記01,初識QTC
          • Qt Creator 源碼學(xué)習(xí)筆記02,認識框架結(jié)構(gòu)結(jié)構(gòu)
          • Qt Creator 源碼學(xué)習(xí)筆記03,大型項目如何管理工程
          • Qt Creator 源碼學(xué)習(xí)筆記04,多插件實現(xiàn)原理分析
          • Qt Creator 源碼學(xué)習(xí)筆記 05,菜單欄是怎么實現(xiàn)插件化的?

          主站蜘蛛池模板: av无码免费一区二区三区| 一区二区在线观看视频| 在线播放国产一区二区三区 | 亚洲天堂一区二区三区四区| 国产精品一区二区久久沈樵| 色婷婷av一区二区三区仙踪林| 国产精品视频一区二区三区四| 一本岛一区在线观看不卡| 成人精品一区二区电影| 亚洲乱码一区av春药高潮| 国产av一区二区三区日韩| 亚洲综合色自拍一区| 一区二区视频传媒有限公司| 成人精品一区二区三区中文字幕| 日本一区午夜爱爱| 视频一区视频二区在线观看| 冲田杏梨AV一区二区三区| 无码国产精品久久一区免费 | 成人毛片一区二区| 天堂一区二区三区在线观看| 亚洲综合无码一区二区痴汉| 亚洲AV无码一区二区三区久久精品| 日韩精品视频一区二区三区 | 一区二区三区福利视频免费观看| 久久亚洲国产精品一区二区| 无码人妻品一区二区三区精99 | 久久精品人妻一区二区三区 | 无码视频免费一区二三区| 97人妻无码一区二区精品免费| 91精品一区二区| 国产精品视频一区二区猎奇| 伊人久久精品无码麻豆一区| 日韩中文字幕一区| asmr国产一区在线| 99无码人妻一区二区三区免费| 无码人妻精品一区二区三区久久 | 亚洲电影国产一区| 国模大尺度视频一区二区| 亚洲一区AV无码少妇电影☆| 熟妇人妻AV无码一区二区三区| 精品国产伦一区二区三区在线观看|