From 0dc9ca86f794ea85a95f97093f5afd956b53108c Mon Sep 17 00:00:00 2001
From: "WIN-C27C5MSVTPO\\16961" <1696136552@qq.com>
Date: Tue, 16 Dec 2025 14:34:09 +0800
Subject: [PATCH] =?UTF-8?q?word=E5=AF=BC=E5=85=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/admin/controller/SkuController.php | 112 ++++++++++++++++++++++++-
1 file changed, 110 insertions(+), 2 deletions(-)
diff --git a/app/admin/controller/SkuController.php b/app/admin/controller/SkuController.php
index 4079c74..bffb8cf 100644
--- a/app/admin/controller/SkuController.php
+++ b/app/admin/controller/SkuController.php
@@ -255,13 +255,121 @@ class SkuController extends BaseController
return true;
}
+ /**
+ * docx 转 HTML(富文本可用,图片上传 OSS)
+ */
+ function docxToHtmlWithImages(string $docxPath): string
+ {
+ if (!is_file($docxPath)) {
+ return '';
+ }
+
+ // 1. 加载 docx
+ $phpWord = WordIOFactory::load($docxPath, 'Word2007');
+
+ // 2. 临时目录(非常重要)
+ $tmpDir = runtime_path('tmp/' . uniqid());
+ if (!is_dir($tmpDir)) {
+ mkdir($tmpDir, 0755, true);
+ }
+
+ $tmpHtml = $tmpDir . '/index.html';
+
+ // 3. 导出 HTML
+ $writer = WordIOFactory::createWriter($phpWord, 'HTML');
+ $writer->save($tmpHtml);
+
+ $html = file_get_contents($tmpHtml);
+
+ // 4. 清洗 Word 垃圾 HTML(关键)
+ $html = $this->cleanWordHtml($html);
+
+ $uploadService = new UploadService();
+
+ // 5. 处理图片
+ $html = preg_replace_callback(
+ '/
]+src="([^"]+)"[^>]*>/i',
+ function ($matches) use ($tmpDir, $uploadService) {
+ $src = $matches[1];
+
+ // 只处理本地图片
+ if (preg_match('#^(http|https|data:)#i', $src)) {
+ return $matches[0];
+ }
+
+ $localImg = realpath($tmpDir . '/' . $src);
+ if (!$localImg || !is_file($localImg)) {
+ return $matches[0];
+ }
+
+ // 上传 OSS
+ $ossUrl = $uploadService->uploadLocalFile([
+ 'path' => $localImg,
+ 'scene' => 'desc'
+ ]);
+
+ return str_replace($src, $ossUrl, $matches[0]);
+ },
+ $html
+ );
+
+ // 6. 清理临时目录
+ $this->deleteDir($tmpDir);
+
+ return trim($html);
+ }
+
+ function deleteDir(string $dir)
+ {
+ if (!is_dir($dir)) return;
+ foreach (scandir($dir) as $file) {
+ if ($file === '.' || $file === '..') continue;
+ $path = $dir . '/' . $file;
+ is_dir($path) ? $this->deleteDir($path) : unlink($path);
+ }
+ rmdir($dir);
+ }
+
+ function cleanWordHtml(string $html): string
+ {
+ // 删除 Word 注释
+ $html = preg_replace('//', '', $html);
+
+ // 删除 style / meta / link
+ $html = preg_replace('/<(style|meta|link)[^>]*>.*?<\/\1>/is', '', $html);
+
+ // 删除 xml 标签
+ $html = preg_replace('/.*?<\/xml>/is', '', $html);
+
+ // 删除 mso-xxx 样式
+ $html = preg_replace('/\s*mso-[^:]+:[^;"]+;?/i', '', $html);
+
+ // 清理 class="Mso..."
+ $html = preg_replace('/class="Mso[^"]*"/i', '', $html);
+
+ // 删除空 span
+ $html = preg_replace('/]*>\s*<\/span>/i', '', $html);
+
+ // 删除 Office 条件注释
+ $html = preg_replace('/.*?/is', '', $html);
+
+ // 只保留 body 内容
+ if (preg_match('/]*>(.*?)<\/body>/is', $html, $m)) {
+ $html = $m[1];
+ }
+
+ return $html;
+ }
+
+
+
/**
* docx 转 HTML(自动上传图片到 OSS)
*
* @param string $docxPath docx 文件绝对路径
* @return string HTML
*/
- function docxToHtmlWithImages(string $docxPath): string
+ /*function docxToHtmlWithImages(string $docxPath): string
{
if (!is_file($docxPath)) {
return '';
@@ -307,7 +415,7 @@ class SkuController extends BaseController
@unlink($tmpHtml);
return $html;
- }
+ }*/
private function extractImages($sheet): array
{