<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <title>FreeXL: xl2sql.c</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <link href="search/search.css" rel="stylesheet" type="text/css"/> <script type="text/javascript" src="search/search.js"></script> <link href="doxygen.css" rel="stylesheet" type="text/css"/> </head> <body onload='searchBox.OnSelectItem(0);'> <!-- Generated by Doxygen 1.7.4 --> <script type="text/javascript"><!-- var searchBox = new SearchBox("searchBox", "search",false,'Search'); --></script> <div id="top"> <div id="titlearea"> <table cellspacing="0" cellpadding="0"> <tbody> <tr style="height: 56px;"> <td style="padding-left: 0.5em;"> <div id="projectname">FreeXL <span id="projectnumber">1.0.0a</span></div> </td> </tr> </tbody> </table> </div> <div id="navrow1" class="tabs"> <ul class="tablist"> <li><a href="index.html"><span>Main Page</span></a></li> <li><a href="pages.html"><span>Related Pages</span></a></li> <li><a href="annotated.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> <li><a href="examples.html"><span>Examples</span></a></li> <li id="searchli"> <div id="MSearchBox" class="MSearchBoxInactive"> <span class="left"> <img id="MSearchSelect" src="search/mag_sel.png" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/> <input type="text" id="MSearchField" value="Search" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/> </span><span class="right"> <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a> </span> </div> </li> </ul> </div> </div> <div class="header"> <div class="headertitle"> <div class="title">xl2sql.c</div> </div> </div> <div class="contents"> <p>xl2sql a simple tool that takes an .xls file as input, and generates a SQL script as output. You can then use the SQL script to load the extracted data info a SQLite / SpatiaLite database.</p> <p>Here is a typical usage example: </p> <div class="fragment"><pre class="fragment"> ./xl2sql comuni_italiani.xls >comuni.sql spatialite italy.sqlite <comuni.sql </pre></div><p>The first command will parse the .xls document, extracting any data and generating the corresponding SQL script. The second command will create and populate a database from the SQL script. When using xl2sql this way, the first worksheet will become database table xl_table_00, the second worksheet will become database table xl_table_01 and so on.</p> <p>As an alternative, if you pass a second argument to xl2sql, this argument will be used as the table prefix. For example: </p> <div class="fragment"><pre class="fragment"> ./xl2sql comuni_italiani.xls italia >comuni.sql spatialite italy2.sqlite <comuni.sql </pre></div><p>This will result in the tables being named italia_00, italia_01 and so on.</p> <p>This sample code provides an example of:</p> <ul> <li>selecting a worksheet to be active</li> <li>retrieving cell values</li> </ul> <div class="fragment"><pre class="fragment"><span class="comment">/* </span> <span class="comment">/ xl2sql.c</span> <span class="comment">/</span> <span class="comment">/ FreeXL Sample code</span> <span class="comment">/</span> <span class="comment">/ Author: Sandro Furieri a.furieri@lqt.it</span> <span class="comment">/</span> <span class="comment">/ ------------------------------------------------------------------------------</span> <span class="comment">/ </span> <span class="comment">/ Version: MPL 1.1/GPL 2.0/LGPL 2.1</span> <span class="comment">/ </span> <span class="comment">/ The contents of this file are subject to the Mozilla Public License Version</span> <span class="comment">/ 1.1 (the "License"); you may not use this file except in compliance with</span> <span class="comment">/ the License. You may obtain a copy of the License at</span> <span class="comment">/ http://www.mozilla.org/MPL/</span> <span class="comment">/ </span> <span class="comment">/ Software distributed under the License is distributed on an "AS IS" basis,</span> <span class="comment">/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License</span> <span class="comment">/ for the specific language governing rights and limitations under the</span> <span class="comment">/ License.</span> <span class="comment">/</span> <span class="comment">/ The Original Code is the FreeXL library</span> <span class="comment">/</span> <span class="comment">/ The Initial Developer of the Original Code is Alessandro Furieri</span> <span class="comment">/ </span> <span class="comment">/ Portions created by the Initial Developer are Copyright (C) 2011</span> <span class="comment">/ the Initial Developer. All Rights Reserved.</span> <span class="comment">/ </span> <span class="comment">/ Contributor(s):</span> <span class="comment">/ Brad Hards</span> <span class="comment">/ </span> <span class="comment">/ Alternatively, the contents of this file may be used under the terms of</span> <span class="comment">/ either the GNU General Public License Version 2 or later (the "GPL"), or</span> <span class="comment">/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),</span> <span class="comment">/ in which case the provisions of the GPL or the LGPL are applicable instead</span> <span class="comment">/ of those above. If you wish to allow use of your version of this file only</span> <span class="comment">/ under the terms of either the GPL or the LGPL, and not to allow others to</span> <span class="comment">/ use your version of this file under the terms of the MPL, indicate your</span> <span class="comment">/ decision by deleting the provisions above and replace them with the notice</span> <span class="comment">/ and other provisions required by the GPL or the LGPL. If you do not delete</span> <span class="comment">/ the provisions above, a recipient may use your version of this file under</span> <span class="comment">/ the terms of any one of the MPL, the GPL or the LGPL.</span> <span class="comment">/ </span> <span class="comment">*/</span> <span class="preprocessor">#include <stdlib.h></span> <span class="preprocessor">#include <stdio.h></span> <span class="preprocessor">#include <string.h></span> <span class="preprocessor">#include "<a class="code" href="freexl_8h.html" title="Function declarations and constants for FreeXL library.">freexl.h</a>"</span> <span class="keyword">static</span> <span class="keywordtype">void</span> make_table_name (<span class="keyword">const</span> <span class="keywordtype">char</span> *prefix, <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> index, <span class="keywordtype">char</span> *table_name) { <span class="comment">/* generating an SQL clean table name */</span> <span class="keywordtype">char</span> buf[2048]; <span class="keywordtype">char</span> *in = buf; <span class="keywordtype">char</span> *out = table_name; sprintf (buf, <span class="stringliteral">"%s_%02u"</span>, prefix, index); <span class="comment">/* masking for SQL */</span> *out++ = <span class="charliteral">'"'</span>; <span class="keywordflow">while</span> (*in != <span class="charliteral">'\0'</span>) { <span class="keywordflow">if</span> (*in == <span class="charliteral">'"'</span>) *out++ = <span class="charliteral">'"'</span>; *out++ = *in++; } *out++ = <span class="charliteral">'"'</span>; *out = <span class="charliteral">'\0'</span>; } <span class="keyword">static</span> <span class="keywordtype">void</span> print_sql_string (<span class="keyword">const</span> <span class="keywordtype">char</span> *<span class="keywordtype">string</span>) { <span class="comment">/* printing a well formatted SQL string */</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *p = string; putchar (<span class="charliteral">','</span>); putchar (<span class="charliteral">' '</span>); putchar (<span class="charliteral">'\''</span>); <span class="keywordflow">while</span> (*p != <span class="charliteral">'\0'</span>) { <span class="keywordflow">if</span> (*p == <span class="charliteral">'\''</span>) { <span class="comment">/* masking any ' as '' */</span> putchar (<span class="charliteral">'\''</span>); } putchar (*p); p++; } putchar (<span class="charliteral">'\''</span>); } <span class="keywordtype">int</span> main (<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[]) { <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> worksheet_index; <span class="keyword">const</span> <span class="keywordtype">char</span> *table_prefix = <span class="stringliteral">"xl_table"</span>; <span class="keywordtype">char</span> table_name[2048]; <span class="keyword">const</span> <span class="keywordtype">void</span> *handle; <span class="keywordtype">int</span> ret; <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> info; <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> max_worksheet; <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> rows; <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> columns; <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> row; <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> col; <span class="keywordflow">if</span> (argc == 2 || argc == 3) { <span class="keywordflow">if</span> (argc == 3) table_prefix = argv[2]; } <span class="keywordflow">else</span> { fprintf (stderr, <span class="stringliteral">"usage: xl2sql path.xls [table_prefix]\n"</span>); <span class="keywordflow">return</span> -1; } <span class="comment">/* opening the .XLS file [Workbook] */</span> ret = <a name="a0"></a><a class="code" href="freexl_8h.html#acbd27ba5bc7b21d4ae32c0542d51f1e4" title="Open the .xls file, preparing for future functions.">freexl_open</a> (argv[1], &handle); <span class="keywordflow">if</span> (ret != <a name="a1"></a><a class="code" href="freexl_8h.html#aefcbd53004ebb5ce8f727c3d4f3ce43e" title="No error, success.">FREEXL_OK</a>) { fprintf (stderr, <span class="stringliteral">"OPEN ERROR: %d\n"</span>, ret); <span class="keywordflow">return</span> -1; } <span class="comment">/* checking for Password (obfuscated/encrypted) */</span> ret = <a name="a2"></a><a class="code" href="freexl_8h.html#ad6dbe072c7a4632853d90f4509bf3aee" title="Query general information about the Workbook and Worksheets.">freexl_get_info</a> (handle, <a name="a3"></a><a class="code" href="freexl_8h.html#a67663a93d47aea78e01e9aa3ee95a7ff" title="Information query for BIFF password protection state.">FREEXL_BIFF_PASSWORD</a>, &info); <span class="keywordflow">if</span> (ret != <a class="code" href="freexl_8h.html#aefcbd53004ebb5ce8f727c3d4f3ce43e" title="No error, success.">FREEXL_OK</a>) { fprintf (stderr, <span class="stringliteral">"GET-INFO [FREEXL_BIFF_PASSWORD] Error: %d\n"</span>, ret); <span class="keywordflow">goto</span> stop; } <span class="keywordflow">switch</span> (info) { <span class="keywordflow">case</span> <a name="a4"></a><a class="code" href="freexl_8h.html#a41d9788be3004120b9ec25add6481639" title="BIFF file is not password protected.">FREEXL_BIFF_PLAIN</a>: <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a5"></a><a class="code" href="freexl_8h.html#a6a60c1c15710566dc4f7aff403fdd008" title="BIFF file is password protected.">FREEXL_BIFF_OBFUSCATED</a>: <span class="keywordflow">default</span>: fprintf (stderr, <span class="stringliteral">"Password protected: (not accessible)\n"</span>); <span class="keywordflow">goto</span> stop; }; <span class="comment">/* querying BIFF Worksheet entries */</span> ret = <a class="code" href="freexl_8h.html#ad6dbe072c7a4632853d90f4509bf3aee" title="Query general information about the Workbook and Worksheets.">freexl_get_info</a> (handle, <a name="a6"></a><a class="code" href="freexl_8h.html#a9586e48f1cd5f906fd6ee9a2295dbda6" title="Information query for BIFF sheet count.">FREEXL_BIFF_SHEET_COUNT</a>, &max_worksheet); <span class="keywordflow">if</span> (ret != <a class="code" href="freexl_8h.html#aefcbd53004ebb5ce8f727c3d4f3ce43e" title="No error, success.">FREEXL_OK</a>) { fprintf (stderr, <span class="stringliteral">"GET-INFO [FREEXL_BIFF_SHEET_COUNT] Error: %d\n"</span>, ret); <span class="keywordflow">goto</span> stop; } <span class="comment">/* SQL output */</span> printf (<span class="stringliteral">"--\n-- this SQL script was automatically created by xl2sql\n"</span>); printf (<span class="stringliteral">"--\n-- input .xls document was: %s\n--\n"</span>, argv[1]); printf (<span class="stringliteral">"\nBEGIN;\n\n"</span>); <span class="keywordflow">for</span> (worksheet_index = 0; worksheet_index < max_worksheet; worksheet_index++) { <span class="keyword">const</span> <span class="keywordtype">char</span> *utf8_worsheet_name; make_table_name (table_prefix, worksheet_index, table_name); ret = <a name="a7"></a><a class="code" href="freexl_8h.html#abba0c9d47eaba2ca2b8a093b03638219" title="Query worksheet name.">freexl_get_worksheet_name</a> (handle, worksheet_index, &utf8_worsheet_name); <span class="keywordflow">if</span> (ret != <a class="code" href="freexl_8h.html#aefcbd53004ebb5ce8f727c3d4f3ce43e" title="No error, success.">FREEXL_OK</a>) { fprintf (stderr, <span class="stringliteral">"GET-WORKSHEET-NAME Error: %d\n"</span>, ret); <span class="keywordflow">goto</span> stop; } <span class="comment">/* selecting the active Worksheet */</span> ret = <a name="a8"></a><a class="code" href="freexl_8h.html#a248e690e125ee15eddacb25aa72b07a3" title="Set the currently active worksheets.">freexl_select_active_worksheet</a> (handle, worksheet_index); <span class="keywordflow">if</span> (ret != <a class="code" href="freexl_8h.html#aefcbd53004ebb5ce8f727c3d4f3ce43e" title="No error, success.">FREEXL_OK</a>) { fprintf (stderr, <span class="stringliteral">"SELECT-ACTIVE_WORKSHEET Error: %d\n"</span>, ret); <span class="keywordflow">goto</span> stop; } <span class="comment">/* dimensions */</span> ret = <a name="a9"></a><a class="code" href="freexl_8h.html#ace1d7e39a8874a9300821c22e5bb9643" title="Query worksheet dimensions.">freexl_worksheet_dimensions</a> (handle, &rows, &columns); <span class="keywordflow">if</span> (ret != <a class="code" href="freexl_8h.html#aefcbd53004ebb5ce8f727c3d4f3ce43e" title="No error, success.">FREEXL_OK</a>) { fprintf (stderr, <span class="stringliteral">"WORKSHEET-DIMENSIONS Error: %d\n"</span>, ret); <span class="keywordflow">goto</span> stop; } printf (<span class="stringliteral">"--\n-- creating a DB table\n"</span>); printf (<span class="stringliteral">"-- extracting data from Worksheet #%u: %s\n--\n"</span>, worksheet_index, utf8_worsheet_name); printf (<span class="stringliteral">"CREATE TABLE %s (\n"</span>, table_name); printf (<span class="stringliteral">"\trow_no INTEGER NOT NULL PRIMARY KEY"</span>); <span class="keywordflow">for</span> (col = 0; col < columns; col++) printf (<span class="stringliteral">",\n\tcol_%03u MULTITYPE"</span>, col); printf (<span class="stringliteral">");\n"</span>); printf (<span class="stringliteral">"--\n-- populating the same table\n--\n"</span>); <span class="keywordflow">for</span> (row = 0; row < rows; row++) { <span class="comment">/* INSERT INTO statements */</span> <a name="_a10"></a><a class="code" href="structFreeXL__CellValue__str.html" title="Container for a cell value.">FreeXL_CellValue</a> cell; printf (<span class="stringliteral">"INSERT INTO %s (row_no"</span>, table_name); <span class="keywordflow">for</span> (col = 0; col < columns; col++) printf (<span class="stringliteral">", col_%03u"</span>, col); printf (<span class="stringliteral">") VALUES (%u"</span>, row); <span class="keywordflow">for</span> (col = 0; col < columns; col++) { ret = <a name="a11"></a><a class="code" href="freexl_8h.html#aef8dc850a668e82b9aa2efde78cc427a" title="Retrieve individual cell values from the currently active worksheet.">freexl_get_cell_value</a> (handle, row, col, &cell); <span class="keywordflow">if</span> (ret != <a class="code" href="freexl_8h.html#aefcbd53004ebb5ce8f727c3d4f3ce43e" title="No error, success.">FREEXL_OK</a>) { fprintf (stderr, <span class="stringliteral">"CELL-VALUE-ERROR (r=%u c=%u): %d\n"</span>, row, col, ret); <span class="keywordflow">goto</span> stop; } <span class="keywordflow">switch</span> (cell.<a name="a12"></a><a class="code" href="structFreeXL__CellValue__str.html#af2b1f157e4dc4508b1c4e303429c01d5" title="The type of data stored in this cell.">type</a>) { <span class="keywordflow">case</span> <a name="a13"></a><a class="code" href="freexl_8h.html#a1a2260897b305108f008c924a7e56778" title="Cell contains an integer value.">FREEXL_CELL_INT</a>: printf (<span class="stringliteral">", %d"</span>, cell.<a name="a14"></a><a class="code" href="structFreeXL__CellValue__str.html#acaf7ae03285c299b05f0e345eff3c6a1" title="The value of the data stored in the cell.">value</a>.<a name="a15"></a><a class="code" href="structFreeXL__CellValue__str.html#a7dcd352478ee217f4a24e7fcff6170bb" title="if type is FREEXL_CELL_INT, then the corresponding value will be returned as int_value">int_value</a>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a16"></a><a class="code" href="freexl_8h.html#a7f2f46b7b391b8b1ff19cef17dd5f4ef" title="Cell contains a floating point number.">FREEXL_CELL_DOUBLE</a>: printf (<span class="stringliteral">", %1.12f"</span>, cell.<a class="code" href="structFreeXL__CellValue__str.html#acaf7ae03285c299b05f0e345eff3c6a1" title="The value of the data stored in the cell.">value</a>.<a name="a17"></a><a class="code" href="structFreeXL__CellValue__str.html#ad125ce4ac1a2dde3bdcfa2750dd0815d" title="if type is FREEXL_CELL_DOUBLE, then the corresponding value will be returned as double_value">double_value</a>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a18"></a><a class="code" href="freexl_8h.html#ab928649db9c51b12efbbf71b248ef1fe" title="Cell contains a text value.">FREEXL_CELL_TEXT</a>: <span class="keywordflow">case</span> <a name="a19"></a><a class="code" href="freexl_8h.html#a357ed1fac1a7e38ac7bf712f178d1ec3" title="Cell contains a reference to a Single String Table entry (BIFF8)">FREEXL_CELL_SST_TEXT</a>: print_sql_string (cell.<a class="code" href="structFreeXL__CellValue__str.html#acaf7ae03285c299b05f0e345eff3c6a1" title="The value of the data stored in the cell.">value</a>.<a name="a20"></a><a class="code" href="structFreeXL__CellValue__str.html#a2f0f6b8e3bb3503487107037a769e56e" title="if type is FREEXL_CELL_TEXT, FREEXL_CELL_SST_TEXT, FREEXL_CELL_DATE, FREEXL_CELL_DATETIME or FREEXL_C...">text_value</a>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a21"></a><a class="code" href="freexl_8h.html#aacf5c5f5606df0b5ee875ec9702819c9" title="Cell contains a number intended to represent a date.">FREEXL_CELL_DATE</a>: <span class="keywordflow">case</span> <a name="a22"></a><a class="code" href="freexl_8h.html#ae51f78f0944809077b4e706044d2f7a7" title="Cell contains a number intended to represent a date and time.">FREEXL_CELL_DATETIME</a>: <span class="keywordflow">case</span> <a name="a23"></a><a class="code" href="freexl_8h.html#abb41208799b5a3ffb42713f58b387577" title="Cell contains a number intended to represent a time.">FREEXL_CELL_TIME</a>: printf (<span class="stringliteral">", '%s'"</span>, cell.<a class="code" href="structFreeXL__CellValue__str.html#acaf7ae03285c299b05f0e345eff3c6a1" title="The value of the data stored in the cell.">value</a>.<a class="code" href="structFreeXL__CellValue__str.html#a2f0f6b8e3bb3503487107037a769e56e" title="if type is FREEXL_CELL_TEXT, FREEXL_CELL_SST_TEXT, FREEXL_CELL_DATE, FREEXL_CELL_DATETIME or FREEXL_C...">text_value</a>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <a name="a24"></a><a class="code" href="freexl_8h.html#ad085ed9c20bfc0ed4006c45588e13fc0" title="Cell has no value (empty cell)">FREEXL_CELL_NULL</a>: <span class="keywordflow">default</span>: printf (<span class="stringliteral">", NULL"</span>); <span class="keywordflow">break</span>; }; } printf (<span class="stringliteral">");\n"</span>); } printf (<span class="stringliteral">"\n-- done: table end\n\n\n\n"</span>); } printf (<span class="stringliteral">"COMMIT;\n"</span>); stop: <span class="comment">/* closing the .XLS file [Workbook] */</span> ret = <a name="a25"></a><a class="code" href="freexl_8h.html#a6122b2adf513c42a8ad5aa0e083a82bb" title="Close the .xls file and releasing any allocated resource.">freexl_close</a> (handle); <span class="keywordflow">if</span> (ret != <a class="code" href="freexl_8h.html#aefcbd53004ebb5ce8f727c3d4f3ce43e" title="No error, success.">FREEXL_OK</a>) { fprintf (stderr, <span class="stringliteral">"CLOSE ERROR: %d\n"</span>, ret); <span class="keywordflow">return</span> -1; } <span class="keywordflow">return</span> 0; } </pre></div> </div> </div> <!-- window showing the filter options --> <div id="MSearchSelectWindow" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" onkeydown="return searchBox.OnSearchSelectKey(event)"> <a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Defines</a></div> <!-- iframe showing the search results (closed by default) --> <div id="MSearchResultsWindow"> <iframe src="javascript:void(0)" frameborder="0" name="MSearchResults" id="MSearchResults"> </iframe> </div> <hr class="footer"/><address class="footer"><small>Generated on Fri Jan 13 2012 for FreeXL by  <a href="http://www.doxygen.org/index.html"> <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.4 </small></address> </body> </html>