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

CodeIgniter导出MS Word文档:本地正常线上异常排查

本地XAMPP正常,线上服务器导出Word格式异常、图片丢失问题分析

问题背景

本地XAMPP环境下,CodeIgniter导出MS Word文档功能完全正常,但部署到线上服务器后,导出的Word文档格式混乱,且图片全部丢失。文本与图片数据均从数据库获取,相关代码如下:

  • 正确/预期格式:文档排版规整,图片正常显示
  • 错误/非预期格式:排版错乱,图片无法加载

相关代码

控制器代码

public function daily_newspaper_report()
{
    $todayDate = '';
    $startDate = $this->input->post('startDate');
    $endDate = $this->input->post('endDate');
    $response['data'] = $this->project_model->daily_newspaper_get($startDate, $endDate);
    if ($startDate == $endDate) {
        $todayDate = date_format(date_create($startDate), "d F Y");
    } else {
        $todayDate = date_format(date_create($startDate), "d F Y") . ' to ' . date_format(date_create($endDate), "d F Y");
    }
    $search_array = array("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ":", ",", "to");
    $replace_array = array("১", "২", "৩", "৪", "৫", "৬", "৭", "৮", "৯", "০", "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগষ্ট", "সেপ্টেম্বার", "অক্টোবার", "নভেম্বার", "ডিসেম্বার", ":", ",", "থেকে");
    $response['publish_date'] = str_replace($search_array, $replace_array, $todayDate);
    $this->load->view('sadmin/daily_newspaper_report', $response);
    header("Content-Type: application/msword");
    header("Content-disposition: attachment; filename=\"Articles on Agriculture & Allied Science_" . date_format(date_create($startDate), "d-M-Y") . " to " . date_format(date_create($endDate), "d-M-Y") . ".doc\"");
}

模型代码

public function daily_newspaper_get($startDate, $endDate)
{
    $sql = "SELECT documents.*, newspaper.newspaper_name AS 'newspaper', newspaper.logo FROM documents JOIN newspaper WHERE documents.newspaper_name=newspaper.id AND publish_date >= '$startDate' AND publish_date <= '$endDate' AND type_id = 7";
    $query = $this->db->query($sql);
    return $query->result();
}

视图代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Daily Newspaper Report</title>
    <meta http-equiv=Content-Type content="text/html; charset=utf-8">
</head>
<body style="font-size: 18.7px;">
    <?php
    // Page Number EN - BN
    function Bengali_DTN($page_no)
    {
        $englDTN = array(
            "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "January", "February", "March", "April", "May", "June", "July", "August", "August", "September", "October", "November", "December", ":", ",", "to"
        );
        $bangDTN = array(
            "১", "২", "৩", "৪", "৫", "৬", "৭", "৮", "৯", "০", "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগষ্ট", "সেপ্টেম্বার", "অক্টোবার", "নভেম্বার", "ডিসেম্বার", ":", ",", "থেকে"
        );
        $converted = str_replace($englDTN, $bangDTN, $page_no);
        return $converted;
    }
    foreach ($data as $singleData) { ?>
        <h1 style="text-align: center"> <img height="50" width="150" src="<?php echo base_url() . $singleData->logo; ?>"></h1>
        <h4 style="text-align: center"><?php echo Bengali_DTN(date_format(date_create($singleData->publish_date), "d F Y")); ?>, পৃষ্ঠা-<?php $page_no = $singleData->accession_num;
                                                                            echo Bengali_DTN($page_no); ?></h4>
        <h1><b><?php echo $singleData->title; ?></b></h1>
        <?php
        if ($this->project_model->newspaper_image_get($singleData->id)) {
            $variable = $this->project_model->newspaper_image_get($singleData->id);
        ?>
            <?php
            foreach ($variable as $value) { ?>
                <img width="300" height="200" src="<?php echo base_url() . $value->imagePath; ?>" alt="">
            <?php }
        }
        if (stristr($singleData->article_details, '<img src=')) { ?>
            <div><?php echo str_replace('<img src=', '<img width="300" height="200" src=', $singleData->article_details); ?></div>
        <?php } else { ?>
            <div><?php echo $singleData->article_details; ?></div>
    <?php }
    }
    ?>
    <h3 style="text-align: center;">Designed and Developed by <span style="font-weight: bold">Computer & GIS Unit</span></h3>
</body>
</html>

问题原因分析

  1. HTTP头输出顺序错误:控制器中先加载视图输出内容,再设置Word的HTTP头。HTTP头必须在任何内容输出前发送,否则服务器会自动发送默认Content-Type,导致Word无法正确解析HTML为规范文档,引发排版混乱。

  2. 图片路径与权限问题:

    • 线上服务器base_url配置与本地不一致,导致生成的图片绝对路径无效,Word无法加载外部图片;
    • 图片文件所在目录权限不足(如未设置为755),服务器无法读取图片资源。
  3. 字符编码兼容性:线上服务器PHP默认字符编码可能与本地不同,导致孟加拉语等非ASCII字符渲染异常,间接影响排版。

  4. SQL注入风险:模型中直接拼接用户输入的日期参数到SQL语句,线上环境可能因特殊字符或安全策略导致查询结果异常,影响输出内容。


解决方案

1. 修正HTTP头输出顺序

将HTTP头设置移到视图加载之前,确保头信息优先发送:

public function daily_newspaper_report()
{
    // ... 原有数据处理逻辑 ...
    
    // 先设置Word相关HTTP头
    header("Content-Type: application/msword");
    header("Content-disposition: attachment; filename=\"Articles on Agriculture & Allied Science_" . date_format(date_create($startDate), "d-M-Y") . " to " . date_format(date_create($endDate), "d-M-Y") . ".doc\"");
    
    // 再加载视图输出内容
    $this->load->view('sadmin/daily_newspaper_report', $response);
}

2. 修复图片路径与权限

  • 检查application/config/config.php中的base_url,确保线上环境指向正确域名/IP:
    $config['base_url'] = 'https://your-domain.com/';
    
  • 将图片目录权限设为755,文件权限设为644,确保服务器可读取。

3. 统一字符编码

  • 在视图<head>中明确编码:
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
  • 线上服务器.htaccess添加编码配置:
    AddDefaultCharset UTF-8
    

4. 修复SQL注入漏洞

使用CodeIgniter查询构造器替代直接拼接SQL:

public function daily_newspaper_get($startDate, $endDate)
{
    $this->db->select('documents.*, newspaper.newspaper_name AS newspaper, newspaper.logo');
    $this->db->from('documents');
    $this->db->join('newspaper', 'documents.newspaper_name = newspaper.id');
    $this->db->where('publish_date >=', $startDate);
    $this->db->where('publish_date <=', $endDate);
    $this->db->where('type_id', 7);
    return $this->db->get()->result();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:29:55