Thinkphp使用pptx模板生成pptx
<?php use DOMDocument; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use ZipArchive; class PptxXmlModifier { private $tempDir; private $namespaceA = 'http://schemas.openxmlformats.org/drawingml/2006/main'; // 1. 解压 PPTX 文件 private function unzip($pptxPath) { //$this->tempDir在$zip->addFile($filePath, $relativePath);使用中;relativePath 必须是 Zip 内部相对路径,使用 正斜杠 /,否则会导致 PPTX 无法打开。 $uniqid_file_path = ROOT_PATH . 'runtime/cache/uniqid/'.'pptx_' . uniqid(); $this->tempDir = str_replace('\\', '/',$uniqid_file_path); if (!is_dir($this->tempDir)) { mkdir($this->tempDir, 0777, true); // 递归创建目录 } $zip = new ZipArchive(); if ($zip->open($pptxPath) === TRUE) { $zip->extractTo($this->tempDir); $zip->close(); return true; } return false; } // 2. 替换文本(保留 Run 样式结构) private function replaceText($replacements) { $slidesPath = $this->tempDir . '/ppt/slides'; $slideFiles = glob($slidesPath . '/slide*.xml'); foreach ($slideFiles as $slideFile) { $dom = new DOMDocument(); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->load($slideFile); // 获取所有 <a:t> 文本节点 $textNodes = $dom->getElementsByTagNameNS($this->namespaceA, 't'); foreach ($textNodes as $node) { $originalText = $node->nodeValue; foreach ($replacements as $placeholder => $newValue) { if (strpos($originalText, $placeholder) !== false) { // 核心:只修改节点的值,完全不触碰父级 <a:r> 和 <a:rPr> 中的任何样式属性 $node->nodeValue = str_replace($placeholder, $newValue, $originalText); } } } $dom->save($slideFile); } } // 3. 替换图片(支持本地路径和 Base64 字符串) private function replaceImage($imageMap) { // $imageMap 格式: ['old_image_filename.jpg' => '新的图片数据'] $mediaDir = $this->tempDir . '/ppt/media'; foreach ($imageMap as $oldName => $newImagepath) { $newImageSource = ROOT_PATH . $newImagepath; // PPT中的目标图片 $targetImage = $mediaDir . '/' . $oldName; if (file_exists($targetImage)) { $data = file_get_contents($newImageSource); if ($data) { // 替换图片 file_put_contents($targetImage, $data); } } } } // 4. 重新打包成新的 PPTX private function save($outputPath) { $zip = new ZipArchive(); if ($zip->open($outputPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) { return false; } $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($this->tempDir), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($files as $file) { if (!$file->isDir()) { $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($this->tempDir) + 1); $zip->addFile($filePath, $relativePath); } } return $zip->close(); } // 清理临时文件 private function cleanup() { if (is_dir($this->tempDir)) { $this->rrmdir($this->tempDir); } } private function rrmdir($dir) { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (is_dir($dir . "/" . $object)) $this->rrmdir($dir . "/" . $object); else unlink($dir . "/" . $object); } } rmdir($dir); } } /** * @param $template 模板 * @param $outputPath 输出文件全路径 * @param $textReplacements 文本更换内容 * @param $imageReplacements 图片更换内容 * @return bool */ public function createpptx($template, $outputPath, $textReplacements, $imageReplacements) { if ($this->unzip($template)) { // 3. 执行替换 $this->replaceText($textReplacements); $this->replaceImage($imageReplacements); // 4. 保存并输出新文件 $this->save($outputPath); $this->cleanup(); return true; } else { return false; } } }
使用
$template = ROOT_PATH . P_STATIC . DS . 'template.pptx'; $file_path = ROOT_PATH . P_STATIC . DS . 'week' . DS . $day; if (!is_dir($file_path)) { mkdir($file_path, 0777, true); // 递归创建目录 } $output = $file_path . DS . $shopid . '.pptx'; $textReplacements = [ '{{username}}' => $user_data['name'], '{{shopname}}' => $shop_data['shop_name'] ]; $feilds = ['1'=>['image3.png','image4.png','image5.png'], '2'=>'image6.png', '3'=>'image7.png', '4'=>'image8.png', '5'=>'image9.png', '6'=>'image10.png', '7'=>'image11.png', '8'=>'image12.png', '9'=>'image13.png', '10'=>'image18.png', '11'=>'image15.png', '12'=>'image16.png', '13'=>'image17.png', '14'=>'image20.png', '15'=>'image19.png', '16'=>'image21.png', '17'=>'image22.png', '18'=>'image23.png', '19'=>'image24.png', '20'=>'image29.png', '21'=>'image14.png']; $imageReplacements = []; foreach ($feilds as $key=>$feild) { if (is_array($feild)){ $pic1_arr = json_decode($picdata['pic'.$key]); foreach ($pic1_arr as $index => $pic1_item) { $imageReplacements[$feild[$index]] = $pic1_item; } }else{ $imageReplacements[$feild]=$picdata['pic'.$key]; } } $modifier = new PptxXmlModifier(); $result = $modifier->createpptx($template, $output, $textReplacements, $imageReplacements);

浙公网安备 33010602011771号