13 private $rows = array();
16 private $celldata =
'';
17 private $colrepeat =
false;
18 private $inrow =
false;
19 private $incell =
false;
20 private $cellattrs = array();
32 throw new Exception(
"ODS convert needs an ODS path and a CSV path");
35 $this->rows = array();
38 $this->colrepeat =
false;
40 $this->incell =
false;
45 if ($isWrited ===
false) {
46 throw new Exception(sprintf(
"Unable to convert ODS to CSV fo %s",
$odsfile));
59 throw new Exception(
"file $odsfile not found");
61 $cibledir = uniqid(
"/var/tmp/ods");
63 $cmd = sprintf(
"unzip -j %s content.xml -d %s >/dev/null",
$odsfile, $cibledir);
66 $contentxml = $cibledir .
"/content.xml";
67 if (file_exists($contentxml)) {
68 $content = file_get_contents($contentxml);
71 throw new Exception(
"unable to extract $odsfile");
86 $xml_parser = xml_parser_create();
88 xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING,
true);
89 xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 0);
90 xml_set_element_handler($xml_parser, array(
97 xml_set_character_data_handler($xml_parser, array(
102 if (!xml_parse($xml_parser, $xmlcontent)) {
103 throw new Exception(sprintf(
"Unable to parse XML : %s line %d", xml_error_string(xml_get_error_code($xml_parser)) , xml_get_current_line_number($xml_parser)));
106 xml_parser_free($xml_parser);
107 foreach ($this->rows as $row) {
115 $parser, $name, $attrs)
118 if ($name ==
"TABLE:TABLE-ROW") {
120 if (isset($this->rows[$this->nrows])) {
124 foreach ($this->rows[$this->nrows] as & $v) {
125 if (!isset($this->rows[$this->nrows][$idx])) {
126 $this->rows[$this->nrows][$idx] =
'';
130 ksort($this->rows[$this->nrows], SORT_NUMERIC);
134 $this->rows[$this->nrows] = array();
137 if ($name ==
"TABLE:TABLE-CELL") {
138 $this->incell =
true;
139 $this->celldata =
"";
140 $this->cellattrs = $attrs;
141 if (!empty($attrs[
"TABLE:NUMBER-COLUMNS-REPEATED"])) {
142 $this->colrepeat = intval($attrs[
"TABLE:NUMBER-COLUMNS-REPEATED"]);
145 if ($name ==
"TEXT:P") {
146 if (isset($this->rows[$this->nrows][$this->ncol])) {
147 if (strlen($this->rows[$this->nrows][$this->ncol]) > 0) {
148 $this->rows[$this->nrows][$this->ncol].=
'\n';
159 if ($name ==
"TABLE:TABLE-ROW") {
161 $i = $this->ncol - 1;
163 if (strlen($this->rows[$this->nrows][$i]) > 0) {
168 array_splice($this->rows[$this->nrows], $i + 1);
169 $this->inrow =
false;
171 if ($name ==
"TEXT:S") {
172 $this->celldata.=
' ';
174 if ($name ==
"TABLE:TABLE-CELL") {
175 $this->incell =
false;
177 if ($this->celldata ===
'') {
178 $this->celldata = $this->getOfficeTypedValue($this->cellattrs);
181 $this->rows[$this->nrows][$this->ncol] = $this->celldata;
183 if ($this->colrepeat > 1) {
184 $rval = $this->rows[$this->nrows][$this->ncol];
185 for ($i = 1; $i < $this->colrepeat; $i++) {
187 $this->rows[$this->nrows][$this->ncol] = $rval;
191 $this->colrepeat = 0;
200 if ($this->inrow && $this->incell) {
207 if (preg_match(
'/\.ods$/',
$filename))
return true;
208 $sys = trim(shell_exec(sprintf(
"file -bi %s", escapeshellarg(
$filename))));
209 if ($sys ==
"application/x-zip")
return true;
210 if ($sys ==
"application/zip")
return true;
211 if ($sys ==
"application/vnd.oasis.opendocument.spreadsheet")
return true;
215 private function getOfficeTypedValue($attrs) {
218 if (isset($attrs[
'OFFICE:VALUE-TYPE'])) {
219 $type = strtoupper($attrs[
'OFFICE:VALUE-TYPE']);
220 $propName =
'OFFICE:' .
$type .
'-VALUE';
221 if (isset($attrs[$propName])) {
222 $value = (string)$attrs[$propName];
226 if (
$value ==
'' && isset($attrs[
'OFFICE:VALUE'])) {
227 $value = (string)$attrs[
'OFFICE:VALUE'];
characterData($parser, $data)
endElement($parser, $name)
foreach($argv as $arg) $cmd
convertOds2Csv($odsfile, $csvfile)
startElement($parser, $name, $attrs)
xmlcontent2csv($xmlcontent)