Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP实现PDF到XML的转换_Php_Xml_Pdf - Fatal编程技术网

使用PHP实现PDF到XML的转换

使用PHP实现PDF到XML的转换,php,xml,pdf,Php,Xml,Pdf,我需要帮助使用PHP将PDF转换为XML。 有一些网站声称这样做。但是他们要收费。 为此,我必须用PHP编写自己的代码。 作为一名PHP新手,我不知道如何完成这项任务。 所以如果有人做过,请帮我 非常感谢您的帮助。将转换为HTML或XML(使用-XML标志),但结果有点混乱。你会得到很多关于文本片段位置的小块信息。如果您想提取文本的段落或部分,这对您没有好处。您可以使用合适的XPath隔离图像吗 如果您确实需要文本的段落或部分,那么您似乎必须试探性地进行。有一个有趣的方法: 在不同区域(如页眉和

我需要帮助使用PHP将PDF转换为XML。 有一些网站声称这样做。但是他们要收费。 为此,我必须用PHP编写自己的代码。 作为一名PHP新手,我不知道如何完成这项任务。 所以如果有人做过,请帮我

非常感谢您的帮助。

将转换为HTML或XML(使用-XML标志),但结果有点混乱。你会得到很多关于文本片段位置的小块信息。如果您想提取文本的段落或部分,这对您没有好处。您可以使用合适的XPath隔离图像吗

如果您确实需要文本的段落或部分,那么您似乎必须试探性地进行。有一个有趣的方法:

  • 在不同区域(如页眉和页脚)隔离文本
  • 收集文本在同一“行”上运行(忽略此处的列)
  • 将缩进转换为层次结构(帮助查找列表,提供裸表/列处理)
  • 合并行以生成段落
  • 进行PDF到XML的转换,可以免费使用。它可能对您的情况有所帮助,因为它可以分别提取图像和标题等内容

    可以找到输入/输出示例

    该页面包含一个简单的


    (披露:这是我的系统。)

    您可以使用该类将pdf解析为字符串,然后使用它=)


    哪个模式?“XML“有点模糊-您是否接受“[此处pdf的全部内容]”作为合理的输出?嗨@Bobby,谢谢您的快速响应。实际上我想把pdf的内容转换成xml。PDF内容可以是任何内容。然后我需要将PDF转换成XML,然后将XML数据插入mysql数据库。我想你的想法也会奏效。现在你告诉我你的方法是否适用于我的情况。我的观点是,你需要更仔细地思考一下你想做什么,并在你的问题中包括一些细节,比如你为什么要这么做。由于PDF和XML本质上是非常不同的格式,因此在它们之间转换非常困难。例如,您的PDF包含-laregly-格式说明。相反,XML包含语义信息。您将需要以某种方式定义如何在两者之间进行映射。如果您所做的只是将PDF插入数据库中,而不是出于任何原因对其进行更改或需要获取其各个部分,那么您可能应该使用,而不必担心将其转换为XML,我不需要修改PDF文档,但我确实需要PDF文档的各个部分。我将把各个部分插入到各自的列中。例如,假设我将PDF文档中的图像插入到一列,将描述插入到另一列。我们可以看到源代码吗?我很想把它用于一个项目,但是把它放在我的服务器上,这样我就可以保证正常运行时间。对不起,现在不是开源的。非常自信的正常运行时间不会成为问题,但是如果你想通过对话的话,请随时联系。@AlexConstantin!这已经不起作用了,你能再次检查吗?@atif我不再维护该端点,但计划很快启动另一台主机。代码中最有趣的部分可在github上找到:
    
    <?php class PDF2Text2 {
    var $multibyte = 4; //
    var $convertquotes = ENT_QUOTES; //
    var $showprogress = true; //
    var $filename = '';
    var $decodedtext = '';
    
    function setFilename($filename) {
        // Reset
        $this->decodedtext = '';
        $this->filename = $filename;
    }
    
    function output($echo = false) {
        if($echo) echo $this->decodedtext;
        else return $this->decodedtext;
    }
    
    function setUnicode($input) {
        // 4 for unicode. But 2 should work in most cases just fine
        if($input == true) $this->multibyte = 4;
        else $this->multibyte = 2;
    }
    
    function decodePDF() {
        // Read the data from pdf file
        $infile = @file_get_contents($this->filename, FILE_BINARY);
        if (empty($infile))
            return "";
    
        // Get all text data.
        $transformations = array();
        $texts = array();
    
        // Get the list of all objects.
        preg_match_all("#obj[\n|\r](.*)endobj[\n|\r]#ismU", $infile . "endobj\r", $objects);
        $objects = @$objects[1];
    
        // Select objects with streams.
        for ($i = 0; $i < count($objects); $i++) {
            $currentObject = $objects[$i];
    
            // Prevent time-out
            @set_time_limit ();
            if($this->showprogress) { //                              echo ". ";
                flush(); ob_flush();
            }
    
            // Check if an object includes data stream.
            if (preg_match("#stream[\n|\r](.*)endstream[\n|\r]#ismU", $currentObject . "endstream\r", $stream )) {
                $stream = ltrim($stream[1]);
                // Check object parameters and look for text data.
                $options = $this->getObjectOptions($currentObject);
    
                if (!(empty($options["Length1"]) && empty($options["Type"]) && empty($options["Subtype"])) )
                if ( $options["Image"] && $options["Subtype"] )
                if (!(empty($options["Length1"]) &&  empty($options["Subtype"])) )
                    continue;
    
                // Hack, length doesnt always seem to be correct
                unset($options["Length"]);
    
                // So, we have text data. Decode it.
                $data = $this->getDecodedStream($stream, $options);
    
                if (strlen($data)) {
                    if (preg_match_all("#BT[\n|\r](.*)ET[\n|\r]#ismU", $data . "ET\r", $textContainers)) {
                        $textContainers = @$textContainers[1];
                        $this->getDirtyTexts($texts, $textContainers);
                    } else
                        $this->getCharTransformations($transformations, $data);
                }
            }
        }
    
        // Analyze text blocks taking into account character transformations and return results.
        $this->decodedtext = $this->getTextUsingTransformations($texts, $transformations);
    }
    
    
    function decodeAsciiHex($input) {
        $output = "";
    
        $isOdd = true;
        $isComment = false;
    
        for($i = 0, $codeHigh = -1; $i < strlen($input) && $input[$i] != '>'; $i++) {
            $c = $input[$i];
    
            if($isComment) {
                if ($c == '\r' || $c == '\n')
                    $isComment = false;
                continue;
            }
    
            switch($c) {
                case '\0': case '\t': case '\r': case '\f': case '\n': case ' ': break;
                case '%':
                    $isComment = true;
                    break;
    
                default:
                    $code = hexdec($c);
                    if($code === 0 && $c != '0')
                        return "";
    
                    if($isOdd)
                        $codeHigh = $code;
                    else
                        $output .= chr($codeHigh * 16 + $code);
    
                    $isOdd = !$isOdd;
                    break;
            }
        }
    
        if($input[$i] != '>')
            return "";
    
        if($isOdd)
            $output .= chr($codeHigh * 16);
    
        return $output;
    }
    
    function decodeAscii85($input) {
        $output = "";
    
        $isComment = false;
        $ords = array();
    
        for($i = 0, $state = 0; $i < strlen($input) && $input[$i] != '~'; $i++) {
            $c = $input[$i];
    
            if($isComment) {
                if ($c == '\r' || $c == '\n')
                    $isComment = false;
                continue;
            }
    
            if ($c == '\0' || $c == '\t' || $c == '\r' || $c == '\f' || $c == '\n' || $c == ' ')
                continue;
            if ($c == '%') {
                $isComment = true;
                continue;
            }
            if ($c == 'z' && $state === 0) {
                $output .= str_repeat(chr(0), 4);
                continue;
            }
            if ($c < '!' || $c > 'u')
                return "";
    
            $code = ord($input[$i]) & 0xff;
            $ords[$state++] = $code - ord('!');
    
            if ($state == 5) {
                $state = 0;
                for ($sum = 0, $j = 0; $j < 5; $j++)
                    $sum = $sum * 85 + $ords[$j];
                for ($j = 3; $j >= 0; $j--)
                    $output .= chr($sum >> ($j * 8));
            }
        }
        if ($state === 1)
            return "";
        elseif ($state > 1) {
            for ($i = 0, $sum = 0; $i < $state; $i++)
                $sum += ($ords[$i] + ($i == $state - 1)) * pow(85, 4 - $i);
            for ($i = 0; $i < $state - 1; $i++) {
                try {
                    if(false == ($o = chr($sum >> ((3 - $i) * 8)))) {
                        throw new Exception('Error');
                    }
                    $output .= $o;
                } catch (Exception $e) { /*Dont do anything*/ }
            }
        }
    
        return $output;
    }
    
    function decodeFlate($data) {
        return @gzuncompress($data);
    }
    
    function getObjectOptions($object) {
        $options = array();
    
        if (preg_match("#<<(.*)>>#ismU", $object, $options)) {
            $options = explode("/", $options[1]);
            @array_shift($options);
    
            $o = array();
            for ($j = 0; $j < @count($options); $j++) {
                $options[$j] = preg_replace("#\s+#", " ", trim($options[$j]));
                if (strpos($options[$j], " ") !== false) {
                    $parts = explode(" ", $options[$j]);
                    $o[$parts[0]] = $parts[1];
                } else
                    $o[$options[$j]] = true;
            }
            $options = $o;
            unset($o);
        }
    
        return $options;
    }
    
    function getDecodedStream($stream, $options) {
        $data = "";
        if (empty($options["Filter"]))
            $data = $stream;
        else {
            $length = !empty($options["Length"]) ? $options["Length"] : strlen($stream);
            $_stream = substr($stream, 0, $length);
    
            foreach ($options as $key => $value) {
                if ($key == "ASCIIHexDecode")
                    $_stream = $this->decodeAsciiHex($_stream);
                elseif ($key == "ASCII85Decode")
                    $_stream = $this->decodeAscii85($_stream);
                elseif ($key == "FlateDecode")
                    $_stream = $this->decodeFlate($_stream);
                elseif ($key == "Crypt") { // TO DO
                }
            }
            $data = $_stream;
        }
        return $data;
    }
    
    function getDirtyTexts(&$texts, $textContainers) {
        for ($j = 0; $j < count($textContainers); $j++) {
            if (preg_match_all("#\[(.*)\]\s*TJ[\n|\r]#ismU", $textContainers[$j], $parts))
                $texts = array_merge($texts, array(@implode('', $parts[1])));
            elseif (preg_match_all("#T[d|w|m|f]\s*(\(.*\))\s*Tj[\n|\r]#ismU", $textContainers[$j], $parts))
                $texts = array_merge($texts, array(@implode('', $parts[1])));
            elseif (preg_match_all("#T[d|w|m|f]\s*(\[.*\])\s*Tj[\n|\r]#ismU", $textContainers[$j], $parts))
                $texts = array_merge($texts, array(@implode('', $parts[1])));
        }
    
    }
    
    function getCharTransformations(&$transformations, $stream) {
        preg_match_all("#([0-9]+)\s+beginbfchar(.*)endbfchar#ismU", $stream, $chars, PREG_SET_ORDER);
        preg_match_all("#([0-9]+)\s+beginbfrange(.*)endbfrange#ismU", $stream, $ranges, PREG_SET_ORDER);
    
        for ($j = 0; $j < count($chars); $j++) {
            $count = $chars[$j][1];
            $current = explode("\n", trim($chars[$j][2]));
            for ($k = 0; $k < $count && $k < count($current); $k++) {
                if (preg_match("#<([0-9a-f]{2,4})>\s+<([0-9a-f]{4,512})>#is", trim($current[$k]), $map))
                    $transformations[str_pad($map[1], 4, "0")] = $map[2];
            }
        }
        for ($j = 0; $j < count($ranges); $j++) {
            $count = $ranges[$j][1];
            $current = explode("\n", trim($ranges[$j][2]));
            for ($k = 0; $k < $count && $k < count($current); $k++) {
                if (preg_match("#<([0-9a-f]{4})>\s+<([0-9a-f]{4})>\s+<([0-9a-f]{4})>#is", trim($current[$k]), $map)) {
                    $from = hexdec($map[1]);
                    $to = hexdec($map[2]);
                    $_from = hexdec($map[3]);
    
                    for ($m = $from, $n = 0; $m <= $to; $m++, $n++)
                        $transformations[sprintf("%04X", $m)] = sprintf("%04X", $_from + $n);
                } elseif (preg_match("#<([0-9a-f]{4})>\s+<([0-9a-f]{4})>\s+\[(.*)\]#ismU", trim($current[$k]), $map)) {
                    $from = hexdec($map[1]);
                    $to = hexdec($map[2]);
                    $parts = preg_split("#\s+#", trim($map[3]));
    
                    for ($m = $from, $n = 0; $m <= $to && $n < count($parts); $m++, $n++)
                        $transformations[sprintf("%04X", $m)] = sprintf("%04X", hexdec($parts[$n]));
                }
            }
        }
    }
    function getTextUsingTransformations($texts, $transformations) {
        $document = "";
        for ($i = 0; $i < count($texts); $i++) {
            $isHex = false;
            $isPlain = false;
    
            $hex = "";
            $plain = "";
            for ($j = 0; $j < strlen($texts[$i]); $j++) {
                $c = $texts[$i][$j];
                switch($c) {
                    case "<":
                        $hex = "";
                        $isHex = true;
                        $isPlain = false;
                        break;
                    case ">":
                        $hexs = str_split($hex, $this->multibyte); // 2 or 4 (UTF8 or ISO)
                        for ($k = 0; $k < count($hexs); $k++) {
    
                            $chex = str_pad($hexs[$k], 4, "0"); // Add tailing zero
                            if (isset($transformations[$chex]))
                                $chex = $transformations[$chex];
                            $document .= html_entity_decode("&#x".$chex.";");
                        }
                        $isHex = false;
                        break;
                    case "(":
                        $plain = "";
                        $isPlain = true;
                        $isHex = false;
                        break;
                    case ")":
                        $document .= $plain;
                        $isPlain = false;
                        break;
                    case "\\":
                        $c2 = $texts[$i][$j + 1];
                        if (in_array($c2, array("\\", "(", ")"))) $plain .= $c2;
                        elseif ($c2 == "n") $plain .= '\n';
                        elseif ($c2 == "r") $plain .= '\r';
                        elseif ($c2 == "t") $plain .= '\t';
                        elseif ($c2 == "b") $plain .= '\b';
                        elseif ($c2 == "f") $plain .= '\f';
                        elseif ($c2 >= '0' && $c2 <= '9') {
                            $oct = preg_replace("#[^0-9]#", "", substr($texts[$i], $j + 1, 3));
                            $j += strlen($oct) - 1;
                            $plain .= html_entity_decode("&#".octdec($oct).";", $this->convertquotes);
                        }
                        $j++;
                        break;
    
                    default:
                        if ($isHex)
                            $hex .= $c;
                        elseif ($isPlain)
                            $plain .= $c;
                        break;
                }
            }
            $document .= "\n";
        }
    
        return $document;
    }}?>