سؤال

أنا أستخدم FUPPCSV في PHP لإخراج ملف مفصل لاستعلام قاعدة البيانات. عند فتح الملف في Gedit في Ubuntu ، يبدو صحيحًا - كل سجل يحتوي على كسر خط (لا يوجد أحرف كسر خط مرئي ، ولكن يمكنك معرفة أن كل سجل يتم فصله ، وفتحه في جدول بيانات OpenOffice يتيح لي عرض الملف بشكل صحيح.)

ومع ذلك ، فإننا نرسل هذه الملفات إلى عميل على Windows ، وعلى أنظمتها ، يأتي الملف كخط طويل كبير. فتحه في Excel ، لا يتعرف على خطوط متعددة على الإطلاق.

لقد قرأت عدة أسئلة هنا متشابهة إلى حد ما ، بما في ذلك هذا, ، والذي يتضمن رابطًا للمعلومات حقًا انشقاق Newline Great تفسير.

لسوء الحظ ، لا يمكننا فقط إخبار عملائنا بفتح الملفات في محرر "أكثر ذكاءً". يجب أن يكونوا قادرين على فتحها في Excel. هل هناك أي طريقة برمجية لضمان إضافة أحرف NewLine الصحيحة بحيث يمكن فتح الملف في برنامج جدول البيانات على أي نظام تشغيل؟

أنا أستخدم بالفعل وظيفة مخصصة لفرض عروض الأسعار حول جميع القيم ، لأن FUPTCSV انتقائي حولها. لقد حاولت فعل شيء مثل هذا:

function my_fputcsv($handle, $fieldsarray, $delimiter = "~", $enclosure ='"'){

        $glue = $enclosure . $delimiter . $enclosure;

    return fwrite($handle, $enclosure . implode($glue,$fieldsarray) . $enclosure."\r\n");

}

ولكن عندما يتم فتح الملف في محرر نصوص Windows ، فإنه لا يزال يظهر كخط طويل واحد.

هل كانت مفيدة؟

المحلول 8

حصلت في النهاية على إجابة في تبادل الخبراء ؛ هذا ما نجح:

function my_fputcsv($handle, $fieldsarray, $delimiter = "~", $enclosure ='"'){
   $glue = $enclosure . $delimiter . $enclosure;
   return fwrite($handle, $enclosure . implode($glue,$fieldsarray) . $enclosure.PHP_EOL);
}

لاستخدامها بدلاً من FPUTCSV القياسي.

نصائح أخرى

// Writes an array to an open CSV file with a custom end of line.
//
// $fp: a seekable file pointer. Most file pointers are seekable, 
//   but some are not. example: fopen('php://output', 'w') is not seekable.
// $eol: probably one of "\r\n", "\n", or for super old macs: "\r"
function fputcsv_eol($fp, $array, $eol) {
  fputcsv($fp, $array);
  if("\n" != $eol && 0 === fseek($fp, -1, SEEK_CUR)) {
    fwrite($fp, $eol);
  }
}

هذه نسخة محسّنة من إجابة John Douthat الرائعة ، مع الحفاظ على إمكانية استخدام المحددات المخصصة والمرفقات وإرجاع الإخراج الأصلي لـ FUPTCSV:

function fputcsv_eol($handle, $array, $delimiter = ',', $enclosure = '"', $eol = "\n") {
    $return = fputcsv($handle, $array, $delimiter, $enclosure);
    if($return !== FALSE && "\n" != $eol && 0 === fseek($handle, -1, SEEK_CUR)) {
        fwrite($handle, $eol);
    }
    return $return;
}

باستخدام وظيفة PHP FUPPCSV يكتب فقط n ولا يمكن تخصيصه. هذا يجعل الوظيفة لا قيمة لها لبيئة Microsoft على الرغم من أن بعض الحزم ستكتشف خط Linux الجديد أيضًا.

لا يزال فوائد FUPTCSV أبقتني في حل في حل لاستبدال الحرف الجديد قبل إرسال الملف مباشرة. يمكن القيام بذلك عن طريق تدفق FUPCSV إلى البناء في تيار Temp PHP أولاً. ثم قم بتكييف حرف (أحرف) NewLine مع كل ما تريد ثم حفظ إلى ملف. مثله:

function getcsvline($list,  $seperator, $enclosure, $newline = "" ){
    $fp = fopen('php://temp', 'r+'); 

    fputcsv($fp, $list, $seperator, $enclosure );
    rewind($fp);

    $line = fgets($fp);
    if( $newline and $newline != "\n" ) {
      if( $line[strlen($line)-2] != "\r" and $line[strlen($line)-1] == "\n") {
        $line = substr_replace($line,"",-1) . $newline;
      } else {
        // return the line as is (literal string)
        //die( 'original csv line is already \r\n style' );
      }
    }

        return $line;
}

/* to call the function with the array $row and save to file with filehandle $fp */
$line = getcsvline( $row, ",", "\"", "\r\n" );
fwrite( $fp, $line);

بدلاً من ذلك ، يمكنك الإخراج بتنسيق UNIX الأصلي ( n فقط) ثم قم بتشغيل UNIX2DOS على الملف الناتج للتحويل إلى r n في الأماكن المناسبة. فقط كن حذرًا من أن بياناتك لا تحتوي على أي n. أيضًا ، أرى أنك تستخدم فاصلًا افتراضيًا لـ ~. جرب فاصل افتراضي من t.

كما Webbiedave أشار إلى (THX!) ربما أنظف طريقة هي استخدام مرشح تيار.

إنه أكثر تعقيدًا قليلاً من الحلول الأخرى ، ولكن حتى يعمل على التدفقات غير القابلة للتحرير بعد الكتابة إليهم (مثل التنزيل باستخدام $handle = fopen('php://output', 'w'); )

ها هو مقاربي:

class StreamFilterNewlines extends php_user_filter {
    function filter($in, $out, &$consumed, $closing) {

        while ( $bucket = stream_bucket_make_writeable($in) ) {
            $bucket->data = preg_replace('/([^\r])\n/', "$1\r\n", $bucket->data);
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }
}

stream_filter_register("newlines", "StreamFilterNewlines");
stream_filter_append($handle, "newlines");

fputcsv($handle, $list, $seperator, $enclosure);
...

لقد كنت أتعامل مع موقف مشابه. إليك الحل الذي وجدت أنه يخرج ملفات CSV مع اتفاقات Windows Friendly Line.

http://www.php.net/manual/en/function.fputcsv.php#90883

لم أتمكن من استخدام منذ أن أحاول بث ملف إلى العميل ولا يمكنني استخدام FSEEKs.

احتياجات Windows \r\n كما Linebreak/النقل إرجاع التحرير والسرد من أجل إظهار خطوط منفصلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top