You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TCPDF页眉显示数据库Blob图片失败问题排查

TCPDF页眉显示数据库Blob图片失败问题排查

需要在TCPDF生成的文档页眉中,显示根据所选公司从数据库获取的Blob图片。测试了多种方案,其中两种在页眉外可正常运行,但在页眉内要么导致页面损坏,要么图片不可见,具体代码如下:

$stmt_antet = $conn->prepare("SELECT antet FROM societati WHERE id_societate = ?");
$stmt_antet->bind_param("s", $id_societate_raport);
        
if (!$stmt_antet->execute()) {
    echo mysqli_errno($conn);
} else {
    $result_antet = $stmt_antet->get_result();
    $row_antet = $result_antet->fetch_assoc();
    $antet = $row_antet['antet'];
}

require_once('tcpdf/examples/tcpdf_include.php');

class MYPDF extends TCPDF {
    public function Header() {
        // 方案1:页面损坏
        $imgdata_m = base64_decode($antet);
        $this->Image('@'.$imgdata_m, 25, 35, 160, 24, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
        
        // 方案2:页面损坏,且在页眉外也无法运行
        $antet_encoded = "data:image/png;base64,".$antet;
        $this->tcpdf->Image("@".$antet_encoded, 25, 35, 160, 24, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
        
        // 方案3:报错:TCPDF ERROR: [Image] Unable to get the size of the image
        $img_base64_encoded = 'data:image/jpg;base64,'.$antet;
        $imageContent = file_get_contents($img_base64_encoded);
        $path = tempnam(sys_get_temp_dir(), 'prefix');
        file_put_contents($path, $imageContent);
        $img = '<img src="' . $path . '">';
        $this->writeHTML($img, 25, 35, 160, 24, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
    }
}

// 页眉外可正常运行的方案1
$imgdata_m = base64_decode($antet);
$pdf->Image('@'.$imgdata_m, 25, 35, 160, 24, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);

// 页眉外可正常运行的方案2
$img_base64_encoded = 'data:image/jpg;base64,'.$antet;
$imageContent = file_get_contents($img_base64_encoded);
$path = tempnam(sys_get_temp_dir(), 'prefix');
file_put_contents($path, $imageContent);
$img = '<img src="' . $path . '">';
$pdf->writeHTML($img, 25, 35, 160, 24, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);

核心问题分析

  1. 变量作用域限制:$antet是在MYPDF类外部定义的变量,类的Header()方法默认无法直接访问外部变量,导致获取的图片数据为空或无效,这是页面损坏的核心原因。
  2. 错误的方法调用:方案2中使用$this->tcpdf->Image是错误的——MYPDF继承自TCPDF,直接调用$this->Image即可,多余的tcpdf属性调用会触发对象不存在的错误。
  3. writeHTML参数错误:方案3中writeHTML的参数用法错误,该方法不支持直接传入位置坐标参数,且临时文件路径在HTML中无法被TCPDF正确解析。

解决方案

方案1:通过构造函数传递图片数据(推荐)

修改MYPDF类,在实例化时传入$antet并存储为类属性,供Header方法调用:

class MYPDF extends TCPDF {
    private $headerImageData;

    public function __construct($imageData, $orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false) {
        parent::__construct($orientation, $unit, $format, $unicode, $encoding, $diskcache, $pdfa);
        $this->headerImageData = $imageData;
    }

    public function Header() {
        if ($this->headerImageData) {
            $imgdata = base64_decode($this->headerImageData);
            $this->Image('@'.$imgdata, 25, 35, 160, 24, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
        }
    }
}

// 实例化时传入图片数据
$pdf = new MYPDF($antet);

方案2:声明全局变量(快速临时方案)

在Header方法内声明$antet为全局变量,使其可以访问外部定义的变量:

class MYPDF extends TCPDF {
    public function Header() {
        global $antet;
        if ($antet) {
            $imgdata_m = base64_decode($antet);
            $this->Image('@'.$imgdata_m, 25, 35, 160, 24, 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
        }
    }
}

方案3:修正writeHTML使用方式

如果要使用writeHTML,需先设置坐标再调用方法,并确保临时文件路径有效:

class MYPDF extends TCPDF {
    private $headerImagePath;

    public function __construct($imagePath, $orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false) {
        parent::__construct($orientation, $unit, $format, $unicode, $encoding, $diskcache, $pdfa);
        $this->headerImagePath = $imagePath;
    }

    public function Header() {
        if ($this->headerImagePath) {
            $img = '<img src="' . $this->headerImagePath . '" width="160" height="24">';
            $this->SetXY(25, 35); // 先设置坐标
            $this->writeHTML($img, true, false, true, false, '');
        }
    }
}

// 提前处理临时文件并传入路径
$img_base64_encoded = 'data:image/jpg;base64,'.$antet;
$imageContent = file_get_contents($img_base64_encoded);
$path = tempnam(sys_get_temp_dir(), 'prefix');
file_put_contents($path, $imageContent);
$pdf = new MYPDF($path);

// 生成文档后记得清理临时文件
// $pdf->Output(...);
// unlink($path);

内容的提问来源于stack exchange,提问作者Sorina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:45:05