Giter Club home page Giter Club logo

Comments (4)

daftspunk avatar daftspunk commented on May 26, 2024 2

Thanks for the detailed investigation here.

We've got a fix coming for this in v3.6.10

We just created the stream from an empty string (as per docs):

$csv = CsvWriter::createFromString();

And then used the existing static call on CharsetConverter (docs):

if (
    $options['encoding'] !== null &&
    $csv->supportsStreamFilterOnWrite()
) {
    CharsetConverter::addTo($csv, 'UTF-8', $options['encoding']);
}

Along with the supportsStreamFilterOnWrite sanity check in case the internals change on us again. Confirming that supportsStreamFilterOnWrite returns true now.

Thanks!

from october.

marcogrueter avatar marcogrueter commented on May 26, 2024

I can confirm the issue, encountered this one myself today and didn't find a good solution yet either.

I tried using the formatter like mentioned in the phpleague docs:

        if ($options['encoding'] !== null) {
            $csv->addFormatter((new CharsetConverter())
                ->inputEncoding('utf-8')
                ->outputEncoding($options['encoding'])
            );
        }

but that lead to other problems and errors. I don't know the CSVWriter well enough, but maybe this helps a bit.

from october.

uematsusoft avatar uematsusoft commented on May 26, 2024

@marcogrueter Hi Marco, I tried your code and it worked for some models but not for others. I ended up keeping my version until a official fix since I don't need character encoding conversion.
The only specific thing that I must do is making the exported csv file compatible with MS Office for Mac OS and Windows.

from october.

marcogrueter avatar marcogrueter commented on May 26, 2024

@uematsusoft Yeah I mostly got either a type conversion error or an error from the file reader (imho BOM related or something).

I just gave it another shot, and I think I got it working with this:

    /**
     * processExportDataAsCsv returns the export data as a CSV string
     */
    protected function processExportDataAsCsv($columns, $results, $options)
    {
        // Parse options
        $options = array_merge([
            'firstRowTitles' => true,
            'savePath' => null,
            'useOutput' => false,
            'fileName' => null,
            'delimiter' => null,
            'enclosure' => null,
            'escape' => null,
            'encoding' => null
        ], $options);

        // Prepare CSV
        $csv = CsvWriter::createFromStream(tmpfile());
        $csv->setOutputBOM(ByteSequence::BOM_UTF8);

        if ($options['delimiter'] !== null) {
            $csv->setDelimiter($options['delimiter']);
        }

        if ($options['enclosure'] !== null) {
            $csv->setEnclosure($options['enclosure']);
        }

        if ($options['escape'] !== null) {
            $csv->setEscape($options['escape']);
        }

        $encoder = (new CharsetConverter())->inputEncoding('UTF-8');

        if ($options['encoding'] !== null) {
            $encoder->outputEncoding($options['encoding']);
        }

        $csv->addFormatter($encoder);

        // Add headers
        if ($options['firstRowTitles']) {
            $headers = $this->getColumnHeaders($columns);
            $csv->insertOne($headers);
        }

        // Add records
        foreach ($results as $result) {
            $data = $this->matchDataToColumns($result, $columns);
            $csv->insertOne($data);
        }

        // Output
        if ($options['useOutput']) {
            $csv->output($options['fileName']);
            return;
        }

        // Save to file
        if ($path = $options['savePath']) {
            $resource = @fopen($path, 'w+');
            if (!is_resource($resource)) {
                throw new SystemException("{$path}: failed to open stream for export: No such file or directory.");
            }
            foreach ($csv->chunk(8192) as $chunk) {
                fwrite($resource, $chunk);
            }
            fclose($resource);
            return;
        }

        return $csv->toString();
    }

on top: use League\Csv\ByteSequence;

export config is just standard, with formatting defaults:

defaultFormatOptions:
    fileFormat: csv_custom
    delimiter: ';'
    enclosure: '"'
    escape: '\'
    encoding: 'utf-8'

I'm not sure about side effects, but I tried a few exports and everything seems fine.
Might help until a real / permanent solution is available.

OCMS version 3.6.8. Check that you got the same version, Looks like there was a change in a recent version, so this patch might not work before that.

from october.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.