将数据转换为word文档时PHP中的偏移量错误

时间:2011-06-26 07:39:31

标签: php codeigniter

获取未定义的偏移量:尝试使用以下代码将1个数据输出到word文档时出现1错误...

在控制器中使用CodeIgniter:

$htmltodoc= new HTML_TO_DOC();
$htmltodoc->createDoc("<h1>Testing data </h1>", "testfile.doc");

在帮助程序目录中,我在下面的一个名为HTML_TO_DOC的类中使用以下函数...

 class HTML_TO_DOC
{
    var $docFile="";
    var $title="";
    var $htmlHead="";
    var $htmlBody="";


    /**
     * Constructor
     *
     * @return void
     */
    function HTML_TO_DOC()
    {
        $this->title="Untitled Document";
        $this->htmlHead="";
        $this->htmlBody="";
    }

    /**
     * Set the document file name
     *
     * @param String $docfile 
     */

    function setDocFileName($docfile)
    {
        $this->docFile=$docfile;
        if(!preg_match("/\.doc$/i",$this->docFile))
            $this->docFile.=".doc";
        return;        
    }

    function setTitle($title)
    {
        $this->title=$title;
    }

    /**
     * Return header of MS Doc
     *
     * @return String
     */
    function getHeader()
    {
        $return  = <<<EOH
         <html xmlns:v="urn:schemas-microsoft-com:vml"
        xmlns:o="urn:schemas-microsoft-com:office:office"
        xmlns:w="urn:schemas-microsoft-com:office:word"
        xmlns="http://www.w3.org/TR/REC-html40">

        <head>
        <meta http-equiv=Content-Type content="text/html; charset=utf-8">
        <meta name=ProgId content=Word.Document>
        <meta name=Generator content="Microsoft Word 9">
        <meta name=Originator content="Microsoft Word 9">
        <!--[if !mso]>
        <style>
        v\:* {behavior:url(#default#VML);}
        o\:* {behavior:url(#default#VML);}
        w\:* {behavior:url(#default#VML);}
        .shape {behavior:url(#default#VML);}
        </style>
        <![endif]-->
        <title>$this->title</title>
        <!--[if gte mso 9]><xml>
         <w:WordDocument>
          <w:View>Print</w:View>
          <w:DoNotHyphenateCaps/>
          <w:PunctuationKerning/>
          <w:DrawingGridHorizontalSpacing>9.35 pt</w:DrawingGridHorizontalSpacing>
          <w:DrawingGridVerticalSpacing>9.35 pt</w:DrawingGridVerticalSpacing>
         </w:WordDocument>
        </xml><![endif]-->
        <style>
        <!--
         /* Font Definitions */
        @font-face
            {font-family:Verdana;
            panose-1:2 11 6 4 3 5 4 4 2 4;
            mso-font-charset:0;
            mso-generic-font-family:swiss;
            mso-font-pitch:variable;
            mso-font-signature:536871559 0 0 0 415 0;}
         /* Style Definitions */
        p.MsoNormal, li.MsoNormal, div.MsoNormal
            {mso-style-parent:"";
            margin:0in;
            margin-bottom:.0001pt;
            mso-pagination:widow-orphan;
            font-size:7.5pt;
                mso-bidi-font-size:8.0pt;
            font-family:"Verdana";
            mso-fareast-font-family:"Verdana";}
        p.small
            {mso-style-parent:"";
            margin:0in;
            margin-bottom:.0001pt;
            mso-pagination:widow-orphan;
            font-size:1.0pt;
                mso-bidi-font-size:1.0pt;
            font-family:"Verdana";
            mso-fareast-font-family:"Verdana";}
        @page Section1
            {size:8.5in 11.0in;
            margin:1.0in 1.25in 1.0in 1.25in;
            mso-header-margin:.5in;
            mso-footer-margin:.5in;
            mso-paper-source:0;}
        div.Section1
            {page:Section1;}
        -->
        </style>
        <!--[if gte mso 9]><xml>
         <o:shapedefaults v:ext="edit" spidmax="1032">
          <o:colormenu v:ext="edit" strokecolor="none"/>
         </o:shapedefaults></xml><![endif]--><!--[if gte mso 9]><xml>
         <o:shapelayout v:ext="edit">
          <o:idmap v:ext="edit" data="1"/>
         </o:shapelayout></xml><![endif]-->
         $this->htmlHead
        </head>
        <body>
        EOH;
    return $return;
    }

    /**
     * Return Document footer
     *
     * @return String
     */
    function getFotter()
    {
        return "</body></html>";
    }

    /**
     * Create The MS Word Document from given HTML
     *
     * @param String $html :: URL Name like http://www.example.com
     * @param String $file :: Document File Name
     * @param Boolean $download :: Wheather to download the file or save the file
     * @return boolean 
     */

    function createDocFromURL($url,$file,$download=false)
    {
        if(!preg_match("/^http:/",$url))
            $url="http://".$url;
        $html=@file_get_contents($url);
        return $this->createDoc($html,$file,$download);    
    }

    /**
     * Create The MS Word Document from given HTML
     *
     * @param String $html :: HTML Content or HTML File Name like path/to/html/file.html
     * @param String $file :: Document File Name
     * @param Boolean $download :: Wheather to download the file or save the file
     * @return boolean 
     */

    function createDoc($html,$file,$download=false)
    {
        if(is_file($html))
            $html=@file_get_contents($html);

        $this->_parseHtml($html);
        $this->setDocFileName($file);
        $doc=$this->getHeader();
        $doc.=$this->htmlBody;
        $doc.=$this->getFotter();

        if($download)
        {
            @header("Cache-Control: ");// leave blank to avoid IE errors
            @header("Pragma: ");// leave blank to avoid IE errors
            @header("Content-type: application/octet-stream");
            @header("Content-Disposition: attachment; filename=\"$this->docFile\"");
            echo $doc;
            return true;
        }
        else 
        {
            return $this->write_file($this->docFile,$doc);
        }
    }

    /**
     * Parse the html and remove <head></head> part if present into html
     */

    function _parseHtml($html)
    {
        $html=preg_replace("/<!DOCTYPE((.|\n)*?)>/ims","",$html);
        $html=preg_replace("/<script((.|\n)*?)>((.|\n)*?)<\/script>/ims","",$html);
        preg_match("/<head>((.|\n)*?)<\/head>/ims",$html,$matches);
        $head=$matches[1];
        preg_match("/<title>((.|\n)*?)<\/title>/ims",$head,$matches);
        $this->title = $matches[1];
        $html=preg_replace("/<head>((.|\n)*?)<\/head>/ims","",$html);
        $head=preg_replace("/<title>((.|\n)*?)<\/title>/ims","",$head);
        $head=preg_replace("/<\/?head>/ims","",$head);
        $html=preg_replace("/<\/?body((.|\n)*?)>/ims","",$html);
        $this->htmlHead=$head;
        $this->htmlBody=$html;
        return;
    }

    /**
     * Write the content int file
     *
     * @param String $file :: File name to be save
     * @param String $content :: Content to be write
     * @param [Optional] String $mode :: Write Mode
     * @return void
     * @access boolean True on success else false
     */

    function write_file($file,$content,$mode="w")
    {
        $fp=@fopen($file,$mode);
        if(!is_resource($fp))
            return false;
        fwrite($fp,$content);
        fclose($fp);
        return true;
    }

}

如果有人能帮我解决这个错误会很棒..非常感谢.. PS

3 个答案:

答案 0 :(得分:2)

 Undefined offset: 1

表示您在没有数组键时尝试读取数组键“1”。这可能意味着你得到它的路线就在这里:

 $head=$matches[1];

 $this->title = $matches[1];

所以你的比赛不包含[1]元素,因此你不会'击中'任何东西。

调试方法:

  • 删除$head=$matches[1];
  • 之后的所有内容
  • 问题仍然存在:你找到了自己的路线。不是吗?这是第二行。
  • 对于问题所在的preg_match,请回显$html(或$head)个变量以查看其内容。请注意,如果它们是html,则不会显示在浏览器中,因此请检查源代码或在命令行上执行此操作。
  • 尝试确定您的var是否包含您期望的内容,以及您是否真的可以与正则表达式匹配。如果不是:修复表达式或var。如果是这样的话:
  • 在preg_match中创建一个包含var硬编码内容的测试文件。问题还存在吗?也许var_dump你的$matches确定
  • 如果问题仍然存在(你现在可能已经解决了问题,但不过):发布测试代码(最后一个带有硬编码的preg_match的测试文件很麻烦)并询问你哪里弄错了。

底线:发布一条MINIMAL代码仍然出错。你一定会在制作这个小问题的过程中找到问题,但如果你不这样做,我们就会更容易帮助你。

答案 1 :(得分:1)

您的代码中没有任何地方您实际上检查过您是否设法成功打开要解析的文档,您也可以向我们展示更多代码,甚至不检查$matches是否有任何内容。我建议你做的第一件事是格式化代码,以便更容易阅读,然后查看一些if语句,以确保设置的东西。 仅仅第二个提示将在未来为您节省无数个小时。

另请注意,数组从[0]开始,因此如果您知道匹配只会存储一个内容,请尝试将$matches[1]更改为$matches[0]

答案 2 :(得分:0)

我要继续说你的问题是你没有好的错误信息,而不是你有一个未定义的索引。

按照曲目来达到这一点:

  1. $head=$matches[1];是未定义的索引。
  2. 通过查找正在使用regexp解析的某些HTML的$matches来检索
  3. head * HUGE * No-no顺便说一句。你应该真正研究一个合法的HTML解析器)
  4. 之所以发生这种情况,是因为任何电话_parseHtml都存在问题。
  5. _parseHtmlcreateDoc调用。
  6. 您将"<h1>Testing data </h1>"作为HTML传递。
  7. 所有这些,如果没有找到索引,你没有传递有效的HTML,所以它无法转换它。试试"<html><head></head><body><h1>Testing data </h1></body></html>"(注意:您的班级不接受<head />作为有效的头标记......这是一个问题)。

    还有其他方面可以改进这个课程。

    1. 您使用的是PHP4风格的OOP。除非PHP4是功能规范的一部分。这是一个很大的禁忌。你希望_parseHtml是私有的......
    2. 有一次我注意到了这一点:
      EOH;
      返回$ return;` 探究是Heredoc does not allow for indented closings。它是大红色字母。我认为他们的意思是。
    3. createDocFromURL不允许使用https
    4. $doc.=$this->htmlBody;(在createDoc中)与紧接其前后的代码不一致 - 所有内容都与get<value>一致,并且该行可以直接访问属性。
    5. 您的课程中有一个 ot 之三(getFotter中的拼写错误)
    6. 如果选择PHP 5,则应使用file_put_contents中的write_file
    7. 您对方法的命名不一致 - write_file v。 getHeader
    8. 我并不想让你失望,但其中大部分都有可能在将来引发问题。你真的应该考虑它们。