草庐IT

PHPExcel_Style_Fill 无限递归

coder 2024-01-02 原文

我使用库 PHPExcel 1.7.9 来处理 Excel 文件。首先,我创建一个模板,对其进行风格化和润色。然后,为了避免样式硬编码,我使用上面提到的库打开该模板,更改一些值并将其另存为新的 .xlsx 文件。

首先,我们从单元格中获取该样式。

$this->styles = array() ;
$this->styles['category'] = $sheet->getStyle("A4");
$this->styles['subcategory'] = $sheet->getStyle("A5");

这是递归函数,显示类别和子类别。

private function displayCategories($categories, &$row, $level = 0){
    $sheet = $this->content ;

    foreach($categories as $category){
        if ($category->hasChildren() || $category->hasItems()){ //Check if the row has changed.
            $sheet->getRowDimension($row)->setRowHeight(20);
            $sheet->mergeCells(Cell::NUMBER . $row . ":" . Cell::TOTAL . $row) ;

            $name = ($level == 0) ? strtoupper($category->name) : str_repeat(" ", $level*6) ."- {$category->name}" ;
            $sheet->setCellValue(Cell::NUMBER . $row, $name) ;
            $sheet->duplicateStyle((($level == 0) ?  $this->styles['category'] : $this->styles['subcategory']), Cell::NUMBER . $row);

            $row++ ;
            if ($category->hasChildren()){
                $this->displayCategories($category->children, $row, $level+1);
            }
        }
    }   
}

问题

如果使用$sheet->duplicateStyle(),由于无限递归,将无法保存文档。

Maximum function nesting level of '200' reached, aborting! <- FATAL ERROR

问题出在下一段代码中,在 PHPExcel_Style_Fill 类中,一个对象一遍又一遍地引用自己。

public function getHashCode() { //class PHPExcel_Style_Fill
    if ($this->_isSupervisor) { 
        var_dump($this === $this->getSharedComponent()); //Always true 200 times
        return $this->getSharedComponent()->getHashCode();
    }
    return md5(
          $this->getFillType()
        . $this->getRotation()
        . $this->getStartColor()->getHashCode()
        . $this->getEndColor()->getHashCode()
        . __CLASS__
    );
}

有解决方法吗?我也接受关于如何将一个单元格的完整样式应用到另一个单元格的任何想法。


解决方案:

正如@MarkBaker 在评论中所说,GitHub 上的分支 develop 确实包含了对错误的修复。

最佳答案

编辑 我添加了一个带有修复的拉取请求:https://github.com/PHPOffice/PHPExcel/pull/251

当您尝试将单元格的样式复制到同一个单元格时会发生这种情况;看看这个:

$phpe = new PHPExcel();
$sheet = $phpe->createSheet();

$sheet->setCellValue('A1', 'hi there') ;
$sheet->setCellValue('A2', 'hi again') ;

$sheet->duplicateStyle($sheet->getStyle('A1'), 'A2');

$writer = new PHPExcel_Writer_Excel2007($phpe);
$writer->save('./test.xlsx');

它会工作得很好。 但是如果我像这样添加另一行:

$sheet->duplicateStyle($sheet->getStyle('A1'), 'A1');

然后bang,调用save方法后开始无限递归

要修复你的代码,你应该修改这部分:

$sheet->duplicateStyle((($level == 0) ?  $this->styles['category'] : $this->styles['subcategory']), Cell::NUMBER . $row);

类似于以下内容:

$style = ($level == 0) ?  $this->styles['category'] : $this->styles['subcategory'];
$targetCoords = Cell::NUMBER . $row;
if($style->getActiveCell() != $targetCoords) {
    $sheet->duplicateStyle($style, $targetCoords);
}

关于PHPExcel_Style_Fill 无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18742595/

有关PHPExcel_Style_Fill 无限递归的更多相关文章

  1. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  2. arrays - 这是 Ruby 中 Array.fill 方法的错误吗? - 2

    这个问题在这里已经有了答案:Arraysmisbehaving(1个回答)关闭6年前。是否应该这样,即我误解了,还是错误?a=Array.new(3,Array.new(3))a[1].fill('g')=>[["g","g","g"],["g","g","g"],["g","g","g"]]它不应该导致:=>[[nil,nil,nil],["g","g","g"],[nil,nil,nil]]

  3. ruby - 递归地将所有数字字符串转换为 Ruby 哈希中的整数 - 2

    我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj

  4. Ruby:标准递归模式 - 2

    我经常迷上ruby​​的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情

  5. ruby - 为什么我用递归得到 "stack level too deep"? - 2

    我有这个ruby代码:defget_sumnreturn0ifn似乎正在为999之前的值工作。当我尝试9999时,它给了我这个:stackleveltoodeep(SystemStackError)所以,我添加了这个:RubyVM::InstructionSequence.compile_option={:tailcall_optimization=>true,:trace_instruction=>false}但什么也没发生。我的ruby版本是:ruby1.9.3p392(2013-02-22revision39386)[x86_64-darwin12.2.1]我还增加了机器的堆栈大

  6. ruby - 构建网络蜘蛛时,应该使用递归吗? - 2

    构建一个深度优先的网络蜘蛛,这意味着它将访问第一页上的所有链接,然后转到每个链接,并访问所有第二页上的链接...你应该使用递归吗?我发现这是CPU密集型的。defrecursion()linkz_on_first_page.eachdo|link|recursion(link)endendrecursion(firstpage) 最佳答案 绝对不是,由于万维网的实际性质,您很快就会遇到问题。当您访问带有主导航部分的网站时,每个页面都链接到其他页面,您就进入了一个无限循环。您可以跟踪您处理了哪些链接,但即便如此,递归循环并不真正适合万

  7. ruby-on-rails - ruby数组奇怪的东西(无限数组) - 2

    当我写下面的代码时:x=[1,2,3]x我得到这个输出:[1,2,3,[...]][1,2,3,[...]][1,2,3,[...]]我不应该只得到[1,2,3,[1,2,3]]吗?解释是什么? 最佳答案 这没什么奇怪的。数组的第四个元素就是数组本身,所以当你求第四个元素时,你得到的是数组,当你求第四个元素的第四个元素时,你得到的是数组,当你求第四个元素时,你得到的是数组。第四个元素的第四个元素的第四个元素的元素......你得到了数组。就这么简单。唯一有点不寻常的是Array#to_s检测到这样的递归,而不是进入无限循环,而是返回

  8. ruby-on-rails - 如何以递归方式将 YAML 文件扁平化为 JSON 对象,其中键是点分隔的字符串? - 2

    例如,如果我有YAML文件en:questions:new:'NewQuestion'other:recent:'Recent'old:'Old'这最终会变成一个json对象,例如{'questions.new':'NewQuestion','questions.other.recent':'Recent','questions.other.old':'Old'} 最佳答案 由于问题是关于在Rails应用程序上使用YAML文件进行i18n,因此值得注意i18ngem提供了一个辅助模块I18n::Backend::Flatten完全像

  9. css - 检测到 Sass 更改但 style.css 仅在我保存时每 5 到 7 次被覆盖 - 2

    我在一台Windows764位机器上使用Sass和Ruby(最新版本),我正在我的家庭服务器上处理一个共享文件夹。(但是,我不得不承认问题本身也出现在服务器上,因为我试图安装Ruby并直接-watch服务器上的文件)。问题如下:如果我第一次保存,检测到变化,我的style.css被直接覆盖。之后,我总是需要保存多达7次才能覆盖style.css。每次都会检测到更改,但不会编译任何内容。这是一个屏幕:>>>Sassiswatchingforchanges.PressCtrl-Ctostop.overwritestyle.css>>>Changedetectedto:E:/Websites

  10. ruby - 为什么尾递归 gcd 比 rubinius 的 while 循环更快 - 2

    我有这两个gcd函数的实现:defgcd1(a,b)ifa==baelsifa>bif(a%b)==0belsegcd1(a%b,b)endelseif(b%a)==0aelsegcd1(a,b%a)endendenddefgcd2(a,b)if(a==b)returnaelsifb>amin,max=a,belsemin,max=b,aendwhile(max%min)!=0min,max=max%min,minendminend函数gcd1是尾递归的,而gcd2使用while循环。我已经验证rubinius通过对阶乘函数进行基准测试来执行TCO,只有阶乘函数基准测试显示递归版本和迭

随机推荐