PHP, ZIP 输出内容到word文档,输出损坏

问题描述 投票:0回答:0

此 PHP 代码定义了一个函数 updateDocument(),它使用特定值更新 Microsoft Word 文档模板并提示用户下载更新后的文档。该函数首先检查模板文档是否存在,如果不存在则返回一条错误消息。然后该函数使用 ZipArchive 打开模板文档并将 document.xml 文件的内容读入字符串。使用 str_replace() 将字符串中的占位符替换为实际数据。该函数创建一个临时文件来保存更新后的文档,并将更新后的 document.xml 与模板文档中的所有其他文件一起添加到新存档中。该函数提示用户保存更新的文件,删除临时文件,并将成功的更新记录到 log.txt 文件中。如果在代码执行期间发生错误,错误消息将记录到同一个 log.txt 文件中并显示给用户。该代码还包括一个带有提交按钮的表单,用于调用 updateDocument() 函数。

问题是输出文件轻微损坏,我不明白为什么,它可以恢复并且包含所有内容。我知道有 api 等可以更有效地实现结果,但我的目标是尽可能保持原始状态。代码示例:

template.docx content:
Name: {name}
E-mail: {email}
Phone: {phone}

在 windows 机器上运行 xampp 8.2.0 VS16 如您所见,我确实尝试记录错误,通过将两个文件(临时 docx 和输出 docx)打开为 zip 存档来比较两个文件,但没有发现任何明显的差异。

function updateDocument($outputFileName) {
  // Check if the template document exists
  if (!file_exists('template.docx')) {
    error_log('The template document could not be found.', 3, 'log.txt');
    echo 'The template document could not be found.';
    return;
  }

  try {
    // Open the template document
    $zip = new ZipArchive();
    $zip->open('template.docx');

    // Read the contents of the document.xml file into a string
    $documentXml = $zip->getFromName('word/document.xml');

    // Replace the placeholders with the actual data
    $documentXml = str_replace('{name}', 'John Doe', $documentXml);
    $documentXml = str_replace('{email}', '[email protected]', $documentXml);
    $documentXml = str_replace('{phone}', '+371 21112333', $documentXml);

    // Close the template document
    $zip->close();

    // Create a temporary file to hold the updated document
    $tempFileName = tempnam(sys_get_temp_dir(), 'updated_document');
    $tempZip = new ZipArchive();
    $tempZip->open($tempFileName, ZipArchive::CREATE);

    // Add the updated document.xml to the new archive
    $tempZip->addFromString('word/document.xml', $documentXml);

    // Add all the other files from the template document to the new archive
    $zip = new ZipArchive();
    $zip->open('template.docx');
    for ($i = 0; $i < $zip->numFiles; $i++) {
      $fileName = $zip->getNameIndex($i);
      if ($fileName != 'word/document.xml') {
        $tempZip->addFromString($fileName, $zip->getFromIndex($i));
      }
    }
    $zip->close();

    // Close the updated document archive
    $tempZip->close();

    // Prompt the user to save the updated file
    header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
    header('Content-Disposition: attachment; filename="' . $outputFileName . '"');
    readfile($tempFileName);

    // Delete the temporary file
    unlink($tempFileName);

    // Log successful update
    error_log('Document updated successfully.', 3, 'log.txt');

  } catch (Exception $e) {
    // Log the error
    error_log('An error occurred: ' . $e->getMessage(), 3, 'log.txt');

    // Handle the error
    echo 'An error occurred: ' . $e->getMessage();
  }
}

// Call the function when the button is pressed
if (isset($_POST['submit'])) {
  updateDocument('updated_document.docx');
}?>
<form method='POST'>
    <input type='submit' name='submit' value='Submit' />
</form>
php xml function zip
© www.soinside.com 2019 - 2024. All rights reserved.