Welcome Guest, Not a member yet? Register   Sign In
CSV Reader Library
#1

[eluser]Unknown[/eluser]
Hello All,

Hope you all are doing fine?

I've started working on Codeigniter lately and quickly got in need of something. A CSVReader library. Searched and found one but the biggest problem with that is what if the csv does not have a first row for columns. Hence, i modified the library to make it work with indexes rather then column names. Here is the code for the csvreader.php library.
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* CSVReader Class
*
* $Id: csvreader.php 147 2007-07-09 23:12:45Z Pierre-Jean $
*
* Allows to retrieve a CSV file content as a two dimensional array.
* The first text line shall contains the column names.
*
* @author        Pierre-Jean Turpeau
* @link        http://www.codeigniter.com/wiki/CSVReader
*/
class CSVReader {

    var $fields;        /** columns names retrieved after parsing */
    var $separator = ',';    /** separator used to explode each line */

    /**
     * Parse a text containing CSV formatted data.
     *
     * @access    public
     * @param    string
     * @return    array
     */
    function parse_text($p_Text) {
        $lines = explode("\n", $p_Text);
        return $this->parse_lines($lines);
    }

    /**
     * Parse a file containing CSV formatted data.
     *
     * @access    public
     * @param    string
     * @return    array
     */
    function parse_file($p_Filepath) {
        $lines = file($p_Filepath);
        //Giving line numbers
        for($i=0;$i<sizeof($lines);$i++)
        {
            if($lines[$i]!='')
            {
                $columnname = split($this->separator, $lines[$i]);
                for($i=0;$i<sizeof($lines);$i++)
                {
                    $columnname[$i]=$i;
                }
                break;                    
            }
        }
        //echo $columnname;
        return $this->parse_lines($lines,$columnname);
    }
    /**
     * Parse an array of text lines containing CSV formatted data.
     *
     * @access    public
     * @param    array
     * @return    array
     */
    function parse_lines($p_CSVLines,$c_Names) {
        $content = FALSE;
        if( !is_array($content) )
        { // the first line contains fields numbers
            $this->fields = $c_Names;
            $content = array();
        }
                
        foreach( $p_CSVLines as $line_num => $line )
        {
            if( $line != '' )
            { // skip empty lines
                $elements = split($this->separator, $line);
                $item = array();
                foreach( $this->fields as $id => $field )
                {
                    if( isset($elements[$id]) )
                    {
                        $item[$field] = $elements[$id];
                    }
                }
               $content[] = $item;
            }
        }
        return $content;
    }
}

Note: Please note that this is for CSV's with no column names. I will be working towards the library that gives both options to the coders to choose from. Read CSV with columna names or with indexes only but that is later.

So now in the view you just have to do this to fetch:
Code:
&lt;?php foreach($csvData as $id=>$fields){?&gt;
                <tr>
                    <td>&lt;?=$fields['0']?&gt;</td>
                   <td>&lt;?=$fields['1']?&gt;</td>
                </tr>
            &lt;?php }?&gt;


Let me know your feedback guys...Awiating Responses.

Regards,

Maddy
#2

[eluser]saijin[/eluser]
Its working, thanks...

Can you please give me a hint on how can I add the pagination class on this library?
#3

[eluser]Jelmer[/eluser]
There's a built in function in PHP which can read a string directly into an array instead of doing the parsing yourself: fgetcsv(). Using built in function will always be faster and I think you currently don't allow for strings enclosed in ", which will cause problems when you try to parse a string like "this, that" because the comma is parsed as a seperator while it's in the enclosed string.

I built a CSV library myself which you can find on BitBucket, I haven't made it public yet because it's not fully tested (I'm using only a small part of it currently) and because I haven't gotten round to writing a User Guide (small start in the Wiki).
Maybe you can find some inspiration in there if you continue developing your own.

EDIT: Sorry, I didn't notice the original post is from 2009.

@saijin
If you're using the above library you could try something like this (example & untested):
Code:
$csv = new CSVReader();
$csv_array = $csv->parse_file('filename.csv');
$page_start = (int) $this->uri->segment(3); // fetch the pagination nr, will be 0 when not set

$this->load->library('pagination');

$config['base_url'] = 'http://example.com/index.php/test/page/';
$config['total_rows'] = count($csv_array);
$config['per_page'] = '20';

$this->pagination->initialize($config);

echo $this->pagination->create_links();

echo '<table>';
for($x = $page_start; $x < $page_nr + 20 && $x < $config['total_rows']; $x++)
{
    echo '<tr>';
    foreach ($csv_array[$x] as $y)
         echo '<td>'.$y.'</td>';
    echo '</tr>';
}
echo '</table>';

If you were using my library you'd have to change the first lines to:
Code:
$csv = Csv::get('filename');
$csv_array = $csv->get_contents();
#4

[eluser]Fons Vandamme[/eluser]
[quote author="ShadowElf" date="1318541029"]my first post Big Grin

excel save text with "quotes" if the field is text with some comma (when you save as CSV)

so I addes a fix

perhaps it helps someone


Code:
&lt;?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* CSVReader Class
*
* $Id: csvreader.php 147 2007-07-09 23:12:45Z Pierre-Jean $
*
* Allows to retrieve a CSV file content as a two dimensional array.
* The first text line shall contains the column names.
*
* @author        Pierre-Jean Turpeau
* @link        http://www.codeigniter.com/wiki/CSVReader
*/



//     function index()  
//    {  
//             $this->load->library('csvreader');  
//      
//             $filePath = './csv/products.csv';  
//      
//             $data['csvData'] = $this->csvreader->parse_file($filePath);  
//      
//             $this->load->view('csv_view', $data);  
//    }  


/*<table cellpadding="0" cellspacing="0">  
    <thead>  
    <th>  
            <td>PRODUCT ID</td>  
            <td>PRODUCT NAME</td>  
            <td>CATEGORY</td>  
            <td>PRICE</td>  
    </th>  
    </thead>  
  
    <tbody>  
            &lt;?php foreach($csvData as $field){?&gt;  
                <tr>  
                    <td>&lt;?=$field['id']?&gt;</td>  
                   <td>&lt;?=$field['name']?&gt;</td>  
                    <td>&lt;?=$field['category']?&gt;</td>  
                    <td>&lt;?=$field['price']?&gt;</td>  
                </tr>  
            &lt;?php }?&gt;  
    </tbody>  
  
</table>
*/






class CSVReader {

    var $fields;        /** columns names retrieved after parsing */
    var $separator = ',';    /** separator used to explode each line */

    /**
     * Parse a text containing CSV formatted data.
     *
     * @access    public
     * @param    string
     * @return    array
     */
    function parse_text($p_Text) {
        $lines = explode("\n", $p_Text);
        return $this->parse_lines($lines);
    }

    /**
     * Parse a file containing CSV formatted data.
     *
     * @access    public
     * @param    string
     * @return    array
     */
    function parse_file($p_Filepath) {
        $lines = file($p_Filepath);
        return $this->parse_lines($lines);
    }
    
/*
added by augustin magdici
for cvs's with quotes >> field1, "field2, with quote", field3, "field, with, quotes,", field 5
  (excel standard save in this format)
*/
function strc($string, $start, $end){
$string = " ".$string;
$ini = strpos($string,$start);
if ($ini == 0) return "";
$ini += strlen($start);
$len = strpos($string,$end,$ini) - $ini;
return substr($string,$ini,$len);
}
function likee($needle,$haystack) {
   $pos = stripos($haystack,$needle);
   if($pos === false) {return false;}
   else { return true; }}

function str_replace_once($needle , $replace , $haystack){
    $pos = strpos($haystack, $needle);
    if ($pos === false) {
    return $haystack;
    }
    return substr_replace($haystack, $replace, $pos, strlen($needle));
}  

//end quote added by augustin magdici


/**
     * Parse an array of text lines containing CSV formatted data.
     *
     * @access    public
     * @param    array
     * @return    array
     */
  
  
  
  
    function parse_lines($p_CSVLines) {
        $content = FALSE;
        foreach( $p_CSVLines as $line_num => $line ){
            if( $line != '' ) {
    
    //added by augustin magdici (quote)
    
    while ($this->likee('"',$line)) {
    $line=$this->str_replace_once('"', "[aaxaa]", $line);
    $line=$this->str_replace_once('"', "[bbxaa]", $line);
    }
  
    while ($this->likee('[aaxaa]',$line)) {
    $x1=$this->strc($line, "[aaxaa]", "[bbxbb]");
    $x2=str_replace(",", "[acomax]", $x1);
    $line=str_replace($x1, $x2, $line);
    $line=$this->str_replace_once('[aaxaa]', '', $line);
    $line=$this->str_replace_once('[bbxbb]', '', $line);
    }
    // end added by augustin magdici (quote)
    
    $elements = explode($this->separator, trim($line));

    
                if( !is_array($content) ) { // the first line contains fields names
                    $this->fields = $elements;
                    $content = array();
                } else {
                    $item = array();
                    foreach( $this->fields as $id => $field ) {
                        if( isset($elements[$id]) ) {
                        $item[$field] = str_replace("[acomax]", ",", $elements[$id]); //some quote change
                        }
                    }
                    $content[] = $item;
                }
            }
        }
        return $content;
    }
}
[/quote]

I added trim to the parse_lines function to check for empty lines.. it didn't work properly for me without it. cheers!

Code:
if(trim($line) != '' ) { // rest of code
#5

[eluser]Unknown[/eluser]
good day.. I'm using codeigniter for 3 weeks and I'm developing a system that save csv file to the web server. i want to know how do i import the content of the the csv file.




Theme © iAndrew 2016 - Forum software by © MyBB