Browse Source

Amelioration du support des retour ligne dans les champ texte des CSV : c'est supporte par le standard et LibreOffice, on le permet donc, mais pas par Excel, on les supprime donc dans le cas ou on fait un export de type csv excel (tsv + charset iso)

v3
Cerdic 2 years ago
parent
commit
67fa28751f
  1. 39
      inc/exporter_csv.php

39
inc/exporter_csv.php

@ -23,13 +23,31 @@ include_spip('inc/texte');
* Exporter un champ pour un export CSV : pas de retour a la ligne,
* et echapper les guillements par des doubles guillemets
*
* NB : on supprime les retours lignes qui sont pourtant supportes par le standard CSV et LibreOffice, mais pas par Excel
*
* @param string $champ
* @return string
*/
function exporter_csv_champ($champ) {
#$champ = str_replace("\r", "\n", $champ);
#$champ = preg_replace(",[\n]+,ms", "\n", $champ);
#$champ = str_replace("\n", ", ", $champ);
$champ = str_replace("\r\n", "\n", $champ);
$champ = str_replace("\r", "\n", $champ);
$champ = preg_replace(",\n\s+,ms", "\n", $champ);
$champ = preg_replace(',\s[\s]+,ms', ' ', $champ);
$champ = str_replace('"', '""', $champ);
return '"' . $champ . '"';
}
/**
* Exporter un champ pour un export CSV sans retour a la ligne,
* (qui sont supportees par le standard CSV et LibreOffice, mais pas par Excel)
*
* et echapper les guillements par des doubles guillemets
*
* @param string $champ
* @return string
*/
function exporter_csv_champ_no_lf($champ) {
$champ = preg_replace(',[\s]+,ms', ' ', $champ);
$champ = str_replace('"', '""', $champ);
@ -40,6 +58,7 @@ function exporter_csv_champ($champ) {
* Exporter une ligne complete au format CSV, avec delimiteur fourni
*
* @uses exporter_csv_champ()
* @uses exporter_csv_champ_no_lf()
*
* @param int $nb
* @param array $ligne
@ -49,11 +68,14 @@ function exporter_csv_champ($champ) {
* @param callable $callback
* @return string
*/
function exporter_csv_ligne_numerotee($nb, $ligne, $delim = ',', $importer_charset = null, $callback=null) {
function exporter_csv_ligne_numerotee($nb, $ligne, $delim = ',', $importer_charset = null, $callback=null, $fonction_exporter_champ=null) {
if ($callback) {
$ligne = call_user_func($callback, $nb, $ligne, $delim, $importer_charset);
}
$output = join($delim, array_map('exporter_csv_champ', $ligne)) . "\r\n";
if (!$fonction_exporter_champ or !function_exists($fonction_exporter_champ)) {
$fonction_exporter_champ = 'exporter_csv_champ';
}
$output = join($delim, array_map($fonction_exporter_champ, $ligne)) . "\r\n";
if ($importer_charset) {
$output = str_replace('’', '\'', $output);
$output = unicode2charset(html2unicode(charset2unicode($output)), $importer_charset);
@ -128,12 +150,15 @@ function inc_exporter_csv_dist($titre, $resource, $options = []) {
$charset = $GLOBALS['meta']['charset'];
$importer_charset = null;
$fonction_exporter_champ = null;
if ($options['delim'] == ',') {
$extension = 'csv';
} else {
$extension = 'xls';
# Excel n'accepte pas l'utf-8 ni les entites html... on transcode tout ce qu'on peut
$charset = 'iso-8859-1';
# Excel n'accepte pas les retours ligne dans les CSV
$fonction_exporter_champ = 'exporter_csv_champ_no_lf';
}
// mais si une option charset est explicite, elle a la priorite
if (!empty($options['charset'])) {
@ -147,7 +172,7 @@ function inc_exporter_csv_dist($titre, $resource, $options = []) {
$output = '';
$nb = 0;
if (!empty($options['entetes']) and is_array($options['entetes'])) {
$output = exporter_csv_ligne_numerotee($nb, $options['entetes'], $options['delim'], $importer_charset, $options['callback']);
$output = exporter_csv_ligne_numerotee($nb, $options['entetes'], $options['delim'], $importer_charset, $options['callback'], $fonction_exporter_champ);
}
// les donnees commencent toujours a la ligne 1, qu'il y ait ou non des entetes
$nb++;
@ -177,7 +202,7 @@ function inc_exporter_csv_dist($titre, $resource, $options = []) {
$length = fwrite($fp, $output);
while ($row = is_array($resource) ? array_shift($resource) : sql_fetch($resource)) {
$output = exporter_csv_ligne_numerotee($nb, $row, $options['delim'], $importer_charset, $options['callback']);
$output = exporter_csv_ligne_numerotee($nb, $row, $options['delim'], $importer_charset, $options['callback'], $fonction_exporter_champ);
$length += fwrite($fp, $output);
$nb++;
}

Loading…
Cancel
Save