【问题标题】:How to delete duplicated rows with PHPExcel如何使用 PHPExcel 删除重复的行
【发布时间】:2015-02-12 10:48:55
【问题描述】:

亲爱的救星们,你好,

几天前我打开了一个线程,询问一种使用 PHPExcel 按单元格值搜索/过滤行的方法。来自这个社区的开发人员拯救了我的一天(再次感谢伙计!!!)。从现在开始我一直在努力解决另一个问题。 ¿ 是否可以使用 PHPExcel 删除所有重复的行? 为了让您处于这是我的示例表:

想要在他的单元格中显示所有具有“I1/027”的行(完成!),但没有重复的行:

Hours | Place | Name
------|-------|-----------------
3     |I1/027 | example1   //------> Want to add it to my list!!!
6     |I2/025 | example2   //------> Ignore this (no I1/027)
7     |I1/030 | example3   //------> Ignore this (no I1/027)
2     |I1/027 | example4   //------> Want to add it to my list!!!
3     |I1/027 | example1   //------> Don't want this row, it's repeated!!!

还有phpexcel代码:

  <?php if(isset($_FILES['file']['name'])) { ?>
   <!-- Container progress bar -->
    <div id="progress" style="width:500px;border:1px solid #ccc;"></div>
   <!-- progress info -->
    <div id="information" style="width"></div>

   <?php require_once 'reader/Classes/PHPExcel/IOFactory.php';
       //Extra functions
        function get_cell($cell, $objPHPExcel){
            //Cell selection
            $objCell = ($objPHPExcel->getActiveSheet()->getCell($cell));
            //taking cell value
            return $objCell->getvalue();
        }
        function pp(&$var){
            $var = chr(ord($var)+1);
            return true;
        }
    //==========Displaying Code
        $name     = $_FILES['file']['name'];
        $tname    = $_FILES['file']['tmp_name'];
        $type     = $_FILES['file']['type'];

        if($type == 'application/vnd.ms-excel')
        { // excel 97 extension
            $ext = 'xls';
        }
        else if($type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        { // excel 2007 and 2010 extensions
            $ext = 'xlsx';
        }else
        { // invalid extension
            echo -1;
            exit();
        }
        $xlsx = 'Excel2007';
        $xls  = 'Excel5';

        //read creator
        $objReader = PHPExcel_IOFactory::createReader($$ext);
        //loading
        $objPHPExcel = $objReader->load($tname);

        $dim = $objPHPExcel->getActiveSheet()->calculateWorksheetDimension();
        // put $start and $end array
        list($start, $end) = explode(':', $dim);

        if(!preg_match('#([A-Z]+)([0-9]+)#', $start, $rslt)){
            return false;
        }
        list($start, $start_h, $start_v) = $rslt;
        if(!preg_match('#([A-Z]+)([0-9]+)#', $end, $rslt)){
            return false;
        }
        list($end, $end_h, $end_v) = $rslt;

        //starting to read excel doc
        $table = "<table class='tabla'>";
        for($v=$start_v; $v<=$end_v; $v++){     
            // calculate progress bar
            $percent = intval($v/$end_v * 100)."%";
            // progress bar update
            echo '<script language="javascript">
            document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#ddd;\">&nbsp;'.$percent.'</div>";
            document.getElementById("information").innerHTML="'.$v.' files processed.";</script>'; 

            // buffer flush
            echo str_repeat(' ',1024*64);
            // send exit to navigator
            flush();
            sleep(0.25);

            //horizontal reading
            $tempRow= "<tr>";
            $contentFound=false;

            for($h=$start_h; ord($h)<=ord($end_h); pp($h)){
                $cellValue = get_cell($h.$v, $objPHPExcel);
                $tempRow.= "<td>";
              if($cellValue !== null){
                  if($cellValue=="I1/027") $contentFound=true;
                       $tempRow.= $cellValue;
       }
     $tempRow.= "</td>";
   }
   $tempRow.= "</tr>";

  if($contentFound) $table.=$tempRow;
    }         
        // process completed
        echo '<script language="javascript">document.getElementById("information").innerHTML="Process completed"</script><br>';
        echo $table;
}?>

找到了我试图利用的这个功能,但没有运气:

function removeDuplicates($inputFileName, $objPHPExcel) {
                $worksheet = $objPHPExcel->getActiveSheet();
                $urn = array();

                  foreach ($worksheet->getRowIterator() as $row) {
                      $rowIndex = $row->getRowIndex();
                      $cellValue = $worksheet->getCell('A'.$rowIndex)->getValue();
                      array_push($urn, $cellValue);
                  }
                  $numberOfURNs = count($urn);

                  for ($rowIndex = $numberOfURNs; $rowIndex != 1; $rowIndex--) {
                   $cellValue = $worksheet->getCell('A'.$rowIndex)->getValue();

                      for ($i = $rowIndex - 2; $i != 0; $i--) {
                        if ($urn[$i] == $cellValue) {
                            $worksheet->removeRow($rowIndex);
                            $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
                            $objWriter->save($inputFileName);
                            break;
                        }
                      }     
                  }
                  return $objPHPExcel = checkExtension($inputFileName);
            }

提前非常感谢!!

【问题讨论】:

  • 您想从 excel 文件中删除该行还是只想在输出中跳过它?
  • 感谢@MarkusMüller 的回复。只是想在输出中跳过它。我想保持 excel 文件原样。
  • 您需要检查整行(无论列数如何)还是只检查示例中的几列?
  • @MarkusMüller 我需要检查整行,如果有一行(或两行)与另一行完全相同,那么打印时只需要显示一行。提交 xls 的行数可能不同,但从一个 xls 到另一个 xls 的列数始终相同。也许将来列数会有所不同,所以我认为最好比较整行。我不知道我是否解释得很好。 : \

标签: javascript php row cell phpexcel


【解决方案1】:

有多种解决方案。它们都有一些缺点。您可以将所有行与 excel 文件中的所有行进行比较,这意味着您需要遍历每一行的整个文件。如果您有 1000 行,那就是 1000 * 1000 次比较。如果您熟悉此表示法,则运行时间为 O(n^2),这基本上意味着如果您的行数增加,它将变得非常慢。

您可以将所有值读入一个数组数组,然后让 PHP 使用 array_unique 来完成这些困难的工作。 PHP 文档中提供了一个将其与多维数组一起使用的示例。它通过序列化内部数组,然后使用 array_unqie 并再次反序列化来工作。我不知道 PHP 中的数组函数是如何实现的,但是序列化/反序列化可能需要很多时间。此外,所有值都存在于内存中,如果您的 Excel 文件很大,这可能会成为问题。

我可以想象的第三种可能性是将所有数据插入数据库,然后让数据库使用 distinct 关键字进行重复检查。因此,只需将其导入导入表,然后使用 insert from select 语句将其插入正确的表中而不会重复。之后再次删除导入表的内容。如果无论如何都必须将数据插入数据库,我认为这将是我的首选解决方案

【讨论】:

  • 非常感谢您的时间和贡献马库斯,我会在做出决定之前仔细考虑。数据库的可能性听起来不错,但这意味着要更改所有代码,而且我对 PhpExcel 不是很熟悉。我只是在业余时间学习这个:) 真的希望在 php excel 中实现一个类来处理重复的行,但它似乎比我预期的要有限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
  • 2019-05-27
  • 2010-09-06
相关资源
最近更新 更多