Excel-Datei einlesen in C/C++

  • C++

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Bartosz.

    Excel-Datei einlesen in C/C++

    Hallo,

    ich habe vorhin eine Möglichkeit gesucht, eine Excel-Datei einzulesen. Über Stack******** bin ich hierher gelangt. Wenn ich das klone und einbinde, kommen Syntaxfehler; ich kann nicht glauben, dass die Entwickler welche gemacht haben. Irgendwas stimmt da nicht mit dem Einbinden.

    Egal jetzt –
    kennt hier jemand eine gute Möglichkeit, eine Excel-Datei in C++ einzulesen?

    Viele Grüße
    Bartosz
    @Bartosz Welche Veranlassung hast Du, eine Excel-Datei in C++ einzulesen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Na das sieht ja mal ordentlich aus, hätte ich gesagt wenn wir mehr Informationen hätten.

    Na wat denn da los, frage ich dich jetzt weil wir mehr Informationen bräuchten. :D

    Was ist denn der Allgemeinbefund?
    Wo brennt denn der high-heel?
    Für doch mal bitte den Schadensbericht etwas meer aus. ("meer" anstelle von "mehr", weil codezean)

    Wie bindest du denn ein? :)
    Das Einbinden von Abhängigkeiten in C++ kann schnell zur schweren Geburt werden, daher nenne ich es auch manchmal gerne "entbinden".
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------
    Hallo zusammen!
    Ich habe in letzter Zeit wieder "Bock" auf C++ und habe mir gedacht, ich baue eine schnelle (daher C++) Datenverarbeitung. Was genau ich mache, schaue ich noch. Das Einbinden von Excel ist die erste Aufgabe – nicht mal das klappt
    :( :D
    @Dksksm Ich meine das neue Format (.xlsx). Dann ist die Library wohl nicht ausreichend? Ich muss auch dazusagen, ich habe zum ersten Mal etwas von GitHub geklont.
    @Elanda Ich starte ein neues, leeres C++Projekt bei Visual Studio 2019 CE. Bei GitHub habe ich auf den grünen Code-Button geklickt und das Ganze gezippt heruntergeladen. Dann in dem Visual-Studio-Projektordner entpackt und im Projekt mit Hinzufügen die Header-Datei xls.h eingebunden. Und dann soll es angeblich funktionieren. Stattdessen meldete VS mir Syntaxfehler in den anderen Headerdateien (da verweist ja die eine Header auf die andere), ein Fehler war z.B. ssize_t statt size_t. Ich habe schon alles wieder gelöscht, deswegen kann ich dir keinen Screenshot machen. Was mir noch einfällt: Es kam auch die Fehlermeldung, dass DWORD mehrdeutig sei. Habe ich auch so noch nicht erlebt.

    Was ist denn der Allgemeinbefund?
    > 50 Fehler

    Das Einbinden von Abhängigkeiten in C++ kann schnell zur schweren Geburt werden, ....
    Ja, habe ich gemerkt xD

    @Dksksm Danke, schau ich mir gleich an.

    Viele Grüße

    Bartosz



    Ich habe mir nun den von @Dksksm angesprochenen Github-Code geklont und versucht einzubinden. Die Header-Datei kann nicht gefunden werden, auch wenn ich den richtigen Pfad eintrage und die Datei ins Projekt einbinde...

    Beiträge zusammengefügt. ~Thunderbolt
    Bilder
    • Screenshot 2021-06-06 153200.png

      39,68 kB, 517×568, 152 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    @Bartosz Was passiert, wenn Du die Datei in *.h umbenennst?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    1.) Wenn ich sie umbenenne in .h, dann kommt weiterhin Datei wurde nicht gefunden.

    C-Quellcode

    1. #include <C:/Users/Name/source/repos/C/Projektname/entpackt/OpenXLSX-master/OpenXLSX-master/library/OpenXLSX.h>


    2.) Belasse ich das bei .hpp, dann gibt es wieder sehr, sehr viele Fehler.

    C-Quellcode

    1. #include <C:/Users/Name/source/repos/C/Projektname/entpackt/OpenXLSX-master/OpenXLSX-master/library/OpenXLSX.hpp>



    Die Header-Datei habe ich so eingebunden:
    Wenn du nicht so viele Extra-Features brauchst, kannst du das auch relativ einfach selbst bauen: xlsx-Dateien sind nur Zip-Dateien (kann man auch einfach umbenennen und dann entpacken), und alle nötigen Informationen liegen da drin in sehr einfach zu verarbeitenden Formaten (hauptsächlich XML) vor. Da ist ein Parser ziemlich schnell geschrieben.
    Ich würde dir wärmstens empfehlen CMake zu lernen.
    Visual Studio unterstützt es schon seit einiger Zeit und CMake ist recht bekannt unter C++ Entwicklern.

    Das erleichtert die Arbeit mit Abhängigkeiten erheblich. (zumindest für Bibliotheken mit einer CMakeLists.txt)
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------
    Hallo zusammen,
    ich melde mich zwar einen Freitag später als gedacht, da ich viel am arbeiten bin, aber ich möchte gerne meine Erfahrungen mit euch teilen.
    Als Erstes habe ich mir Winzip heruntergeladen. Ich habe mich von der dauerhaft aufploppenden Werbung "Kaufen Sie jetzt..." nicht verärgern lassen und habe die Excel-Datei entzippt. Wenn man die Excel-Datei aktualisiert, muss man ja ständig neu entzippen – das ist zwar keine gute Lösung, aber ich habe es gemacht, um einen Schritt weiterzukommen. Aus Übungszwecken.


    Es ist mir gelungen, einen File-Parser zu schreiben. Ich möchte hiermit anmerken, dass ich Neuronen abgefragt habe, die für die Sprache C, vor langer Zeit, kreiert wurden. Wenn jemand Verbesserungsvorschläge hat, immer her damit
    :) , aber bitte keine Sprüche "du benutzt C in einer cpp-Datei" – das weiß ich :whistling: .

    Abfolge der Funktion
    parse_file():
    • xml-Datei in ein char[][] kopieren. In meinem Fall ergibt es sich, dass alles in all_Lines[1][] steht. all_Lines[0][] enthält für diese Aufgabe nur unnützes Zeug.
    • Es wird der String "A1" kreiert und es wird in der xml-Datei mittels strstr danach gesucht. Das gibt eine Position zurück. Es wird geprüft, ob er nicht "A1" nebst activeCell gefunden hat, und weiter gehts.
    • mit der Funktion Substring() finde ich dann das Wort DATE( oder <v>, um an gute Positionen für die letztentlichen Werte zu kommen. Ich prüfe auch, ob ich wirklich in unmittelbarer Nähe bin. Beispiel: Das Wort DATE( steht ja nur ein paar Zeichen später in der Datei als "A1".
    • Dasselbe für "B1" und "C1"
    • und all das wiederum nochmal für weitere Zeilen.

    Der Code behandelt 2 Fehler, die einem in die Quere kommen könnten:
    1.) Für den Fall, dass in einer Zelle nichts steht (zum Beispiel B2 und B3 im Bild
    Excel Möglichkeit 2.png), wird das abgefangen.
    2.) Das Programm macht sich auf die Suche nach den Strings A1, A2, A3, B1, usw. und es kann passieren, dass die aktive Zelle gerade auch einer gesuchten entspricht, dann steht in der xml-Datei
    activeCell=B4, was natürlich abgefangen wird.

    Edit: Code etwas eingestampft.

    C-Quellcode

    1. #pragma warning(disable : 4996) // Visual Studio will alte Funktionen, wie zum Beispiel ‚scanf‘, nicht sehen.
    2. #include <stdio.h>
    3. #include <windows.h>
    4. #include <cstdint>
    5. #define how_many_characters_are_read 10000
    6. void Groesse_und_Position_und_Farbe()
    7. {
    8. /*===============================================
    9. Größe der Konsole ändern, Position auf
    10. (0/0) und Farbe ändern.
    11. ===============================================*/
    12. //Größe
    13. HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    14. CONSOLE_SCREEN_BUFFER_INFOEX csbiInfo{};
    15. csbiInfo.cbSize = sizeof(csbiInfo);
    16. GetConsoleScreenBufferInfoEx(hStdout, &csbiInfo);
    17. csbiInfo.srWindow.Right = 25;
    18. csbiInfo.srWindow.Bottom = 50;
    19. SetConsoleScreenBufferInfoEx(hStdout, &csbiInfo);
    20. //Start-Position
    21. HWND consoleWindow = GetConsoleWindow();
    22. SetWindowPos(consoleWindow, 0, 500, 120, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    23. //Farben
    24. csbiInfo.ColorTable[0] = RGB(96, 96, 125); // Dunkelblau-Grau
    25. csbiInfo.ColorTable[1] = RGB(255, 237, 171); // Sehr helles Gelb-Orange (fast Weiß)
    26. SetConsoleScreenBufferInfoEx(hStdout, &csbiInfo);
    27. SetConsoleTextAttribute(hStdout, 1);
    28. system("color 01");
    29. }
    30. // ich verwende übrigens diese Funktion, weil itoa nicht mehr Standard ist.
    31. const char* uint16_t_to_String(uint16_t number)
    32. {
    33. static char buffer[6]{};
    34. sprintf(buffer, "%d", number);
    35. return &buffer[0];
    36. }
    37. bool Check_whether_it_is_not_the_cell_nearby_the_word_activeCell(char* cell_found)
    38. {
    39. if (cell_found != nullptr)
    40. {
    41. if (*(cell_found - 12ll) != 'a' &&
    42. *(cell_found - 11ll) != 'c' &&
    43. *(cell_found - 10ll) != 't' &&
    44. *(cell_found - 9ll) != 'i' &&
    45. *(cell_found - 8ll) != 'v' &&
    46. *(cell_found - 7ll) != 'e' &&
    47. *(cell_found - 6ll) != 'C' &&
    48. *(cell_found - 5ll) != 'e' &&
    49. *(cell_found - 4ll) != 'l' &&
    50. *(cell_found - 3ll) != 'l' &&
    51. *(cell_found - 2ll) != '=')
    52. {
    53. return true;
    54. }
    55. else
    56. {
    57. return false;
    58. }
    59. }
    60. else
    61. {
    62. return false;
    63. }
    64. }
    65. char* Substring(char *big_string, size_t length, char *search_word, size_t Length_of_search_word, size_t Position_from_where_the_search_is_done)
    66. {
    67. for (size_t j = Position_from_where_the_search_is_done; j < (length - (size_t)4); j++)
    68. {
    69. if (Length_of_search_word == (size_t)3)
    70. {
    71. if (big_string[j] == search_word[0] &&
    72. big_string[j + 1] == search_word[1] &&
    73. big_string[j + 2] == search_word[2] )
    74. {
    75. return &(big_string[j]);
    76. }
    77. }
    78. else if (Length_of_search_word == (size_t)5)
    79. {
    80. if (big_string[j] == search_word[0] &&
    81. big_string[j + 1] == search_word[1] &&
    82. big_string[j + 2] == search_word[2] &&
    83. big_string[j + 3] == search_word[3] &&
    84. big_string[j + 4] == search_word[4])
    85. {
    86. return &(big_string[j]);
    87. }
    88. }
    89. }
    90. return nullptr;
    91. }
    92. bool parse_file()
    93. {
    94. uint16_t us0 = (uint16_t)0;
    95. uint16_t us1 = (uint16_t)1;
    96. uint16_t line = us0;
    97. char all_Lines[10][how_many_characters_are_read]{};
    98. char filename[] = "C:/Users/meinPfad/einzulesen - Kopie/xl/worksheets/sheet1.xml";
    99. FILE* XMLfile = fopen(filename, "r");
    100. if (XMLfile == nullptr)
    101. {
    102. printf("\nError: the file \"%s\" could not be opened.\n", filename);
    103. getchar();
    104. return false;
    105. }
    106. while (fgets(all_Lines[line], how_many_characters_are_read-1, XMLfile) != NULL)
    107. {
    108. line += us1;
    109. }
    110. fclose(XMLfile);
    111. /*all_Lines[][] durchgehen*/
    112. uint16_t cnt = us1;
    113. bool successful = false;
    114. for (int i = 1; i < 10; i++)
    115. {
    116. if (all_Lines[i][0] == '\0')
    117. {
    118. break;
    119. }
    120. do
    121. {
    122. /*Zahl als String*/
    123. char Number_as_String[6]{};
    124. const char* Pointer_pointing_to_the_NumberString = uint16_t_to_String(cnt);
    125. strcpy(Number_as_String, Pointer_pointing_to_the_NumberString);
    126. /*-------------------------------------------------------------------*/
    127. /* macht „"A1"“ etc draus */
    128. char Acell[5]{};
    129. strcat(Acell, "\x22"); // "
    130. strcat(Acell, "A");
    131. strcat(Acell, Number_as_String);
    132. strcat(Acell, "\x22"); // "
    133. //Find the string for the A-cell in the xml file!
    134. char* cell_found = strstr(all_Lines[i], Acell);
    135. bool Test1 = Check_whether_it_is_not_the_cell_nearby_the_word_activeCell(cell_found);
    136. if (cell_found != nullptr && Test1)
    137. {
    138. successful = true;
    139. printf("Zelle %s gefunden an Stelle %I64d\n", Acell, cell_found - all_Lines[i] + 1ll);
    140. char DATE_as_Char_Array[] = {'D','A','T','E','('};
    141. char* Word_DATE_found = Substring(all_Lines[i], sizeof(all_Lines[1]), DATE_as_Char_Array, sizeof(DATE_as_Char_Array), static_cast<size_t>(cell_found - all_Lines[i] + 1ll));
    142. if (Word_DATE_found != nullptr && ((Word_DATE_found - all_Lines[i] + 1ll) - (cell_found - all_Lines[i] + 1ll) < 20ll))
    143. {
    144. printf("Ein Datum gefunden an Stelle %I64d\n", Word_DATE_found - all_Lines[i] + 1ll);
    145. }
    146. else
    147. {
    148. successful = false;
    149. }
    150. }
    151. else
    152. {
    153. successful = false;
    154. }
    155. /*-------------------------------------------------------------------*/
    156. /* macht „"B1"“ etc draus */
    157. char Bcell[5]{};
    158. strcat(Bcell, "\x22"); // "
    159. strcat(Bcell, "B");
    160. strcat(Bcell, Number_as_String);
    161. strcat(Bcell, "\x22"); // "
    162. //Find the string for the B-cell in the xml file!
    163. char* cell_found2 = strstr(all_Lines[i], Bcell);
    164. bool Test2 = Check_whether_it_is_not_the_cell_nearby_the_word_activeCell(cell_found2);
    165. if (cell_found2 != nullptr && Test2)
    166. {
    167. successful = true;
    168. printf("Zelle %s gefunden an Stelle %I64d\n", Bcell, cell_found2 - all_Lines[i] + 1ll);
    169. char V_as_Char_Array[] = { '<','v','>' };
    170. char* Word_V_found = Substring(all_Lines[i], sizeof(all_Lines[1]), V_as_Char_Array, sizeof(V_as_Char_Array), static_cast<size_t>(cell_found2 - all_Lines[i] + 1ll));
    171. if (Word_V_found != nullptr && ((Word_V_found - all_Lines[i] + 1ll) - (cell_found2 - all_Lines[i] + 1ll) < 12ll))
    172. {
    173. printf("Wert f\x81 \br Spalte B gefunden an Stelle %I64d\n", Word_V_found - all_Lines[i] + 1ll);
    174. //cnt += us1;
    175. }
    176. else
    177. {
    178. printf("Kein Wert in Spalte %s.\n", Bcell);
    179. //cnt += us1;
    180. }
    181. }
    182. else
    183. {
    184. successful = false;
    185. }
    186. /*-------------------------------------------------------------------*/
    187. /* macht „"C1"“ etc draus */
    188. char Ccell[5]{};
    189. strcat(Ccell, "\x22"); // "
    190. strcat(Ccell, "C");
    191. strcat(Ccell, Number_as_String);
    192. strcat(Ccell, "\x22"); // "
    193. //Find the string for the C-cell in the xml file!
    194. char* cell_found3 = strstr(all_Lines[i], Ccell);
    195. bool Test3 = Check_whether_it_is_not_the_cell_nearby_the_word_activeCell(cell_found3);
    196. if (cell_found3 != nullptr && Test3)
    197. {
    198. successful = true;
    199. printf("Zelle %s gefunden an Stelle %I64d\n", Ccell, cell_found3 - all_Lines[i] + 1ll);
    200. char V_as_Char_Array[] = { '<','v','>' };
    201. char* Word_V_found = Substring(all_Lines[i], sizeof(all_Lines[1]), V_as_Char_Array, sizeof(V_as_Char_Array), static_cast<size_t>(cell_found3 - all_Lines[i] + 10ll));
    202. if (Word_V_found != nullptr )
    203. {
    204. printf("Wert f\x81 \br Spalte C gefunden an Stelle %I64d\n", Word_V_found - all_Lines[i] + 1ll);
    205. cnt += us1;
    206. }
    207. else
    208. {
    209. printf("Kein Wert in Spalte %s.\n", Ccell);
    210. cnt += us1;
    211. }
    212. }
    213. else
    214. {
    215. successful = false;
    216. }
    217. /*-------------------------------------------------------------------*/
    218. printf("\n");
    219. } while (successful);
    220. }
    221. return true;
    222. }
    223. int main(void)
    224. {
    225. Groesse_und_Position_und_Farbe();
    226. bool successful = parse_file();
    227. if (!successful)
    228. {
    229. printf("\nError in data set.\n");
    230. getchar();
    231. return 0;
    232. }
    233. // Programmlaufzeit beenden.
    234. printf("\n");
    235. system("pause");
    236. return 0;
    237. }


    Das waren nur 273 Zeilen (hahahaha)

    Gibt es eine Möglicheit, diese eingelesenen Werte (Datum, Zahl, Zahl) zusammenhängend zu speichern? Zeile für Zeile?

    Bilder
    • Excel Möglichkeit 1.png

      2,87 kB, 247×95, 951 mal angesehen
    • Excel Möglichkeit 2.png

      3,23 kB, 247×121, 952 mal angesehen
    • XML Möglichkeit 1.png

      87,51 kB, 855×961, 70 mal angesehen
    • XML Möglichkeit 2.png

      84,97 kB, 840×934, 62 mal angesehen
    • Konsole.png

      40,16 kB, 998×850, 130 mal angesehen

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Bartosz“ ()