From 14d07ebdc0dc99ec3a37915c8a8dc74c0a3e5960 Mon Sep 17 00:00:00 2001 From: Jay Two Date: Thu, 8 Aug 2024 16:57:05 +0900 Subject: [PATCH] new function for saving to csv file --- QXlsx/header/xlsxdocument.h | 2 + QXlsx/header/xlsxdocument_p.h | 2 + QXlsx/source/xlsxdocument.cpp | 115 ++++++++++++++++++++++++++++++++++ csv/csv.pro | 45 +++++++++++++ csv/main.cpp | 44 +++++++++++++ csv/test.qrc | 6 ++ csv/test.xlsx | Bin 0 -> 4459 bytes 7 files changed, 214 insertions(+) create mode 100644 csv/csv.pro create mode 100644 csv/main.cpp create mode 100644 csv/test.qrc create mode 100644 csv/test.xlsx diff --git a/QXlsx/header/xlsxdocument.h b/QXlsx/header/xlsxdocument.h index 85ad347..688612e 100644 --- a/QXlsx/header/xlsxdocument.h +++ b/QXlsx/header/xlsxdocument.h @@ -118,6 +118,8 @@ public: bool saveAs(const QString &xlsXname) const; bool saveAs(QIODevice *device) const; + bool saveAsCsv(const QString mainCSVFileName) const; + // copy style from one xlsx file to other static bool copyStyle(const QString &from, const QString &to); diff --git a/QXlsx/header/xlsxdocument_p.h b/QXlsx/header/xlsxdocument_p.h index 978df5e..5638dfe 100644 --- a/QXlsx/header/xlsxdocument_p.h +++ b/QXlsx/header/xlsxdocument_p.h @@ -23,6 +23,8 @@ public: bool loadPackage(QIODevice *device); bool savePackage(QIODevice *device) const; + bool saveCsv(const QString mainCSVFileName) const; + // copy style from one xlsx file to other static bool copyStyle(const QString &from, const QString &to); diff --git a/QXlsx/source/xlsxdocument.cpp b/QXlsx/source/xlsxdocument.cpp index 9b58675..d2b1d03 100644 --- a/QXlsx/source/xlsxdocument.cpp +++ b/QXlsx/source/xlsxdocument.cpp @@ -470,6 +470,111 @@ bool DocumentPrivate::savePackage(QIODevice *device) const return true; } +// +// j2doll/csv branch +// +// Save from XLSX to CSV +bool DocumentPrivate::saveCsv(QString mainCSVFileName) const +{ + Q_Q(const Document); + + int sheetIndexNumber = 0; + foreach (QString curretnSheetName, q->sheetNames()) + { + + QXlsx::AbstractSheet *currentSheet = q->sheet(curretnSheetName); + + if (NULL == currentSheet) + { + continue; + } + + // get full cells of sheet + int maxRow = -1; + int maxCol = -1; + + currentSheet->workbook()->setActiveSheet(sheetIndexNumber); + + Worksheet *wsheet = (Worksheet *) currentSheet->workbook()->activeSheet(); + if (NULL == wsheet) + { + continue; + } + + QString strSheetName = wsheet->sheetName(); // sheet name + + QVector clList = wsheet->getFullCells(&maxRow, &maxCol); + + QVector> cellValues; + for (int rc = 0; rc < maxRow; rc++) + { + QVector tempValue; + + for (int cc = 0; cc < maxCol; cc++) + { + tempValue.push_back(QString("")); + } + + cellValues.push_back(tempValue); + } + + for (int ic = 0; ic < clList.size(); ++ic) + { + CellLocation cl = clList.at(ic); + + int row = cl.row - 1; + int col = cl.col - 1; + + std::shared_ptr ptrCell = cl.cell; // cell pointer + QVariant var = ptrCell->value(); + QString str = var.toString(); + + cellValues[row][col] = str; + } + + // TODO: + // (1) save as csv file name (using { mainCSVFileName + strSheetName }) + + QString csvFileName = mainCSVFileName + QString("_") + strSheetName + QString(".csv"); + QFile csvFile(csvFileName); + if ( ! csvFile.open( QIODevice::WriteOnly ) ) + { + continue; + } + + // (2) save sheet values + // such as A,,B,,,,C,,,D,, + + for (int rc = 0; rc < maxRow; rc++) + { + for (int cc = 0; cc < maxCol; cc++) + { + + QString cellData = cellValues[rc][cc]; + + if ( cellData.size() >= 0 ) + { + csvFile.write( cellData.toUtf8() ); // cell data + } + + csvFile.write( QString(",").toLatin1() ); // delimeter + } + + csvFile.write( QString("\n").toLatin1() ); // CR + + csvFile.flush(); + } + + // file.flush(); + + csvFile.close(); + + } // foreach (QString curretnSheetName, q->sheetNames()) ... + + + return true; +} + bool DocumentPrivate::copyStyle(const QString &from, const QString &to) { // create a temp file because the zip writer cannot modify already existing zips @@ -1278,6 +1383,16 @@ bool Document::saveAs(QIODevice *device) const return d->savePackage(device); } + +bool Document::saveAsCsv(const QString mainCSVFileName) const +{ + Q_D(const Document); + + return d->saveCsv( mainCSVFileName ); +} + + + bool Document::isLoadPackage() const { Q_D(const Document); diff --git a/csv/csv.pro b/csv/csv.pro new file mode 100644 index 0000000..2162eeb --- /dev/null +++ b/csv/csv.pro @@ -0,0 +1,45 @@ +# csv.pro + +TARGET = csv +TEMPLATE = app + +QT += core +QT += gui + +CONFIG += console +CONFIG -= app_bundle + +# NOTE: You can fix value of QXlsx path of source code. +# QXLSX_PARENTPATH=./ +# QXLSX_HEADERPATH=./header/ +# QXLSX_SOURCEPATH=./source/ +include(../QXlsx/QXlsx.pri) + +########################################################################## +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +########################################################################## +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain +# version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 +# disables all the APIs deprecated before Qt 6.0.0 + +########################################################################## +# source code + +SOURCES += \ +main.cpp + +# RESOURCES += \ +# test.qrc + +RESOURCES += \ + test.qrc + + diff --git a/csv/main.cpp b/csv/main.cpp new file mode 100644 index 0000000..6a53629 --- /dev/null +++ b/csv/main.cpp @@ -0,0 +1,44 @@ +// main.cpp + +#include +// using namespace std; + +#include +#include +#include +#include +#include +#include + +#include "xlsxcellrange.h" +#include "xlsxchart.h" +#include "xlsxchartsheet.h" +#include "xlsxdocument.h" +#include "xlsxrichstring.h" +#include "xlsxworkbook.h" + + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + + { + using namespace QXlsx; + + QString xlsxFileName = ":/test.xlsx"; + QXlsx::Document xlsxDoc(xlsxFileName); + if (!xlsxDoc.isLoadPackage()) { + return 0; // failed to load + } + + QString csvFileName = "hello.csv"; + if ( xlsxDoc.saveAsCsv(csvFileName) ){ + qDebug() << "save as csv file"; + } + + } + + + return 0; +} diff --git a/csv/test.qrc b/csv/test.qrc new file mode 100644 index 0000000..55f7b89 --- /dev/null +++ b/csv/test.qrc @@ -0,0 +1,6 @@ + + + + test.xlsx + + diff --git a/csv/test.xlsx b/csv/test.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6f1b3a8f4eb5ba33aee2e2e4d89266a99db98f42 GIT binary patch literal 4459 zcmaJ^2{@GP*T-0fETa(bAaC|CsBEDjB4o*yeIg^v82gspnCweq-y%z7O=QcGt?Z(S z>}w_=dTEAHe53x?$JhJ)JI{4J%XQu7ey;m>&iS45)6)V_vXB9RKr-xApefl2J4Jej zxx*12;*g_z1!hGmM+kg+Bo)7`#OY!_mO2ZJPk z4wm>}ajV0`>dNAsBF@GL+ZkK`aA!*x;L!FHKJqDk)_!(B&NzY)p7!kNnp%XY!UJ8v7?m5si zxbVsY54i@QTEamyMtim2{{5>FL3=2fo)!(zt~9KEo^)(^3Nq67e*@+((h6UM_%CdH zT-=>(TwI(WzRrkWI3@Pebx44&6MjTX_-BowBQJaLUaQxK@)W+Ksnh7`Qa_xH%x7zI zU2tsJmL*)Az)SC}hs9qhpel5upnq}Es2EKC#=Xs?Q##=}06!YR>L{-zI&FXY?R^)S z>?B9GL>6$&m79)B)T<~@hI;)RTU0;>pU9V1jzrz`@)F91e9h35f^OJ{CzbMO`GO&U zBlK>2Z-SyekLGyZ*)6QwJXvl%?BLyj<8+jn>Y>IK678CRY3)$u$PJKf0~~>nKtVy) zLONnP`JX^w`US$t~6wT7(hA95j z=A&xr5RHF}DxBC|VZb@~c~lk==wH)S*sw7IRzmx{{>EOlo8umBkM(0~ywHH9v+*YH zM;dRY3OX}pjL{?viGXY9s!exW2SrL6xjs{~z%`v6#6hzZ!$T z=Cist_Q$1Ow6l*NN2;=1Kd2h0Y$>66G;!58=yd7Z;`EVdh|7A?rCileRx#HrnQ{9c z#3BRHl3D2ONWY$%eSE%+H0>u7;n?frU5{NempMvcYa>brSy9tN#H!+HbW@Vm2Y3FZ z%Dgchp&O0&tgj11JvRkvroTMzo~Xz;nDvf=GVC!?^&G1k&|IIoPq&FDQtGkgcGXlP z5uDf)^-%)Y!NxYUJCeU|Rm3MX5!|a0J)k7WQ_R1@6&E>?KzL`LIq+nJ$1I{inH?#J zVk-D*n}~dujD$?^ZSM%K_C1Dt(zrroWB9>G(E9?Zo$@HI_G(bX@r=i3=yuOcG4J@p z%Y(>|QYR*zE&G6!Hr{|gr4GZd)ba52L%=Sn{l(rHS9C2+0^bRV`+=rGCnrl`N? z16{#oVfxqHhURtGzghDY#qF>8z~$m|g6N+|6eS9-a?f~p2JkZrk92Fg?kK&m*3{XW z7wU@aQ!To=awgzqdZ0pQkI8w1j+DYP7PnC1i%buzS&O&B^kbBiGif2^Vo<734Y~`F za{Bx!5*T5zNVFaLRTWE?bRrk zQqG+l`)sx3T%NIh5j)yLVxGpRo^oLjF_ju_zsVtTKHB+WO=SXN;v3q}2;40O6a^E-zO zducK?EsLgwA^EMG;0`uxXKr`8sg6aJ=w&K~)|$U+o>=%2VwNh~6D+QlTDczgysIpv zSY5l1D#V#N;)S+MB)4uud9uyH`{=mR!(o)yT1tlC^NPQSNZqF6_&< z8Q6+EVYj_H(laKgRQK6} z-QvwB=^(^`aMakwN$LlEiuRFb&q8jz8)~Q!=sl8#UD#VypxFOIM6oHNSC@bV%s*4@i8qAVee!I;C zbz0gM3jj4`NZ z@f1%0GZP6tvP?xu20VO1X*Rv#J)H>}>?{zxcvo(0=R8N=ESqZH4Gm7F)13QA$>2n;XD*ky{&QgwqSJq#9%zhJJnY z_U!|XOk(~i3b9<)YFo*1SGs3sbyiW;dNRs^(H;lU27R`h_W8leJvHrLX!B#`&&@m* zw`kH$AKnE{i;mp4xQQEK&R}!y`sa#`H%E0-d=D`axb`_lE7--YY=^4)^f1FJ%I=bA z;SSZHRk9~xEypzVh5V1t`B?k621Sjv;EyNqB(W1ydR8+i@>(-@_R!|Er-DLMxsJg$xAV!0bRadZV#55~^Z`f{0Hpd%^7-kg3 zFB#qbh)eZo(Z!fzx>g7Iw3j6FQ^@dMx3R;ss1A{;^x1#zH4`}cpzPv70zN*qKi0+J z?6Q$@_zB_cWtHw_>KE-v`Er^|bBzjyc@+Yj5xqKzi(d;0=R}bElIP~jq}iWR#i#OP zzqDUQUg(Q4E@v6;1glr9wNL1WELIjrl~vw?Z%_e+#I@FwYMm+v<&0cr_3ry9W!pAmFao(^V0@TQ!IE)w}18S`~C;Vmz7DrmBH|s%%o(li9l5)pK`o^$@@7 z;toG5X=io1m?A`VOWgFIpV_K6P^K({)*^bMeZ7 z&kv4`S(4pjcTCJ{?li?LK&xm(X5OE>@^L^I4P|d|RE$FTZ+6{5WC}RE&XLN7cIL+5 z>XBHJ5^p1Vy$lbvbgIuU#5@8RuMM_Kio`OBY<8bIKc89Z2*w*AJ-_cvno^g}1Zd~L z!sX3q=Lr#sZfJRASP$=6H1iGUmIjd>ssO>2a26G4WY3~qGPHX)!f%dN)vdyn#wR*- zYITbSnw|g*L+CpHSWNPP3?`xBcT$2@jr_WyesHG9z*9IeFkR2A>fAQ@@ z(CYomO|nXneG}B$B4KpTIyB%u3`E3SAO8iLMPv63(aWEJ%oP)WAHX4%8+0}gX{Dv@ zb1^V$&Tek{1S90s^s1$V!pDp2&({3;=if)QhiEql*v4Dmyu;r!3Jd*o&4Oz*`0;4e zyFj-o?!Xnv$*`}Pf_GTvM#uOo&EX*rMPa9i>n+A%#p}SSl1;Kr9INlG!P4tSy3&1& zcL^`DeYW2$BJ=vizlYrLRTB_LjXp0IZjH$4nTmOjAR0d8#DzlR7PHFM&mO_Xfs^{Y zM*=1DkMsH&(h74G7o;Z~=?OFRbA@|Y{%lXl{W_h$)Jl&z%S(7DNOO`Zf#37iSWj0{ z*X5udZ>@bo?2P_n4BLeZ#>NUBxM^@dL_p*{T+7w!FG~zF7lz&w9*))4cyy0xPbwpp zrW@hhe(ytBpvELJ)u10>-CefXCS`=&vqvRc`E@rJ zHedw39)z9(L;5tlU#`ZKU|gN#O}~b~*~-dq7*>n zQVcPaG@ahO-E8_Pt&qa;(Uy@E;}&!ABk%u3j9J#0H#JkcCtaNtJV4`E zJYkLn84GonR6L$Bfaxz&MHqszPVVLrW zQ^+Y;$c~luNojectpBf_(AmE`o|I!p%JbMbNWc2;I`sE_PR`~>;_cYDN%cnB=cJVT z-TCAkbTqynn