Как автоматически установить заголовок, когда это не первая строка файла? - PullRequest
0 голосов
/ 21 июня 2019

Все файлы csv, над которыми я работаю, имеют различное количество строк перед заголовком. Мне нужно установить заголовок автоматически в соответствии с файлом.

Вот пример файла:

            Wine Directory List



            Wine Title  Vintage Country Region  Sub region  Appellation Color   Bottle Size Price   URL FORMAT
Chateau Petrus Pomerol  2011    France  Bordeaux    Pomerol     Red 750ML   2799.99 HTTP://holbrookliquors.com/sku218758.html   1x750ML
Pappy Van Winkle's Bourbon 15 Year Family Reserve       United States   Kentucky                0ML 999.99      1x0ML
Shipping Fee                            0ML 999.99  1x0ML
Heineken Holland Beer       Netherlands                 0ML 999.99  1x0ML

Вот мой конвертер:

ОБНОВЛЕНИЕ: первая часть решения: getHeaderLine (). Единственный недостаток: поскольку я начал синтаксический анализ файла с помощью getHeaderLine (), я не могу получить данные из HeaderLine, так как уже прочитал строку в getHeaderLine. Пожалуйста, кто-нибудь, помогите мне.

public function convert($filePath, $feedColumnsMatch)
{

    //this array will contain the elements from the file
    $articles = [];

    $headerRecord = [];

        //if we can open the file on mode "read"
        if (($handle = fopen($filePath, 'r')) !== FALSE) {
            //represents the line we are reading
            $rowCounter = 0;
            $nb = $feedColumnsMatch->getNumberOfColumns();

            $headerLine = $this->getHeaderLine($handle, $nb, $delimiter);

            //as long as there are lines
            while (($rowData = fgetcsv($handle, 5000, $delimiter)) !== FALSE) {
//todo enlever le vilain 9
                if ($nb===count($rowData)) {

                    //At x line, are written the keys so we record them in $headerRecord
 //What I had first     if (9 === $rowCounter) {
//What I now have
                        if(0 === $rowCounter) {
                        //trim the titles of columns
                        for ($i = 0; $i < $nb; $i++) {
                            $rowData[$i] = trim($rowData[$i]);
                        }

                        $headerRecord = $rowData;
                    }
                    elseif(9<$rowCounter )
                    {      //for every other lines...
                        foreach ($rowData as $key => $value) {       //in each line, for each value
                            // we set $value to the cell ($key) having the same horizontal position than $value
                            // but where vertical position = 0 (headerRecord[]
                            $articles[$rowCounter][$headerRecord[$key]] = mb_convert_encoding($value, "UTF-8");

                        }
                    }
                }
                $rowCounter++;
            }
            fclose($handle);
        }

    return $articles;
}

 public function getHeaderLine($handle, $nbColumns, $delimiter){
        $rowCounter = 0;
        while (($rowData = fgetcsv($handle, 5000, $delimiter)) !== FALSE) {
            $rowCounter++;
            if ($nbColumns===count($rowData)){
                return $rowCounter;
            }

        }
        return -1;
    } 

Как видите, я должен написать "9" в if (), чтобы иметь возможность правильно анализировать данные и изменять их для каждого файла.

1 Ответ

0 голосов
/ 24 июня 2019

Если у вас есть файлы csv / tsv, которые начинаются с разного числа недопустимых строк (пустых или заголовков, тегов или чего-либо еще), решение для получения заголовка состоит в том, чтобы проанализировать файл в первый раз благодаря побочной функции. Первая строка с правильным количеством ячеек (вы должны знать, сколько столбцов имеет ваш CSV-файл) - это ваш заголовок. Таким образом, вы можете вернуть данные заголовка в основную функцию и продолжить анализ с того места, где вы перестал читать в боковой функции.

Весь код:

public function convert($filePath, $feedColumnsMatch)
    {

        if(!file_exists($filePath) ) {
            return "existe pas";
        }
        if(!is_readable($filePath)) {
            return "pas lisible";
        }

        //this array will contain the elements from the file
        $articles = [];

        if($feedColumnsMatch->getFeedFormat()==="tsv" | $feedColumnsMatch->getFeedFormat()==="csv"){
            if($feedColumnsMatch->getFeedFormat()==="csv"){
                $delimiter = $feedColumnsMatch->getDelimiter();
            }else{
                $delimiter = "\t";
            }

            //if we can open the file on mode "read"
            if (($handle = fopen($filePath, 'r')) !== FALSE) {
                //represents the line we are reading

                $nb = $feedColumnsMatch->getNumberOfColumns();
                $headerRecord = $this->getHeader($handle, $nb, $delimiter);           // With this function, I start parsing the file till line === $headerLine
                $rowCounter = 0;
                //if there is no header
                if (null!==$headerRecord || false!==$headerRecord) {
                    //as long as there are lines
                    while (($rowData = fgetcsv($handle, 5000, $delimiter)) !== FALSE) {

                        //if it is a line with valid number of cells
                        if ($nb === count($rowData)) {

                            foreach ($rowData as $key => $value) {       //in each line, for each value
                                // we set $value to the cell ($key) having the same horizontal position than $value
                                // but where vertical position = 0 (headerRecord[]
                                $articles[$rowCounter][$headerRecord[$key]] = mb_convert_encoding($value, "UTF-8");
                            }
                        }
                        $rowCounter++;
                    }
                }
                else{
                    new \Exception();
                }
                fclose($handle);
            }
        }
        return $articles;
    }


    /**
     * is used to get the data of the row containing the header of the csv file or null if no header
     * @param $handle
     * @param $nbColumns
     * @param $delimiter
     * @return array|false|null
     */
    public function getHeader($handle, $nbColumns, $delimiter){
        $rowCounter = 0;
        while (($rowData = fgetcsv($handle, 5000, $delimiter)) !== FALSE) {
            $rowCounter++;
            if ($nbColumns===count($rowData)){
                //trim the titles of columns
                for ($i = 0; $i < $nbColumns; $i++) {
                    $rowData[$i] = trim($rowData[$i]);
                }

                return $rowData;
            }
        }
        return null;
    }

Однако я не знаю, правильно ли это сделать. Это просто способ, который работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...