diff --git a/app/admin/controller/SkuController.php b/app/admin/controller/SkuController.php
index 8f420fe..0544f19 100644
--- a/app/admin/controller/SkuController.php
+++ b/app/admin/controller/SkuController.php
@@ -264,10 +264,8 @@ class SkuController extends BaseController
return '';
}
- // 1. 读取 docx
- $phpWord = WordIOFactory::load($docxPath);
+ $phpWord = \PhpOffice\PhpWord\IOFactory::load($docxPath);
- // 2. 导出 HTML
$tmpDir = runtime_path('tmp/' . uniqid());
if (!is_dir($tmpDir)) {
mkdir($tmpDir, 0755, true);
@@ -275,48 +273,37 @@ class SkuController extends BaseController
$tmpHtml = $tmpDir . '/index.html';
- $writer = WordIOFactory::createWriter($phpWord, 'HTML');
+ $writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'HTML');
$writer->save($tmpHtml);
$html = file_get_contents($tmpHtml);
- // 3. 只取 body 内容(关键)
- if (preg_match('/
]*>(.*?)<\/body>/is', $html, $m)) {
- $html = $m[1];
- }
-
- // 4. 清洗 Word 垃圾样式(关键)
- $html = $this->cleanWordHtml($html);
-
- // 5. 处理图片并上传 OSS
+ // 1️⃣ 上传图片到 OSS
$uploadService = new UploadService();
-
$html = preg_replace_callback(
'/
]+src="([^"]+)"[^>]*>/i',
- function ($matches) use ($tmpDir, $uploadService) {
- $src = $matches[1];
+ function ($m) use ($tmpDir, $uploadService) {
+ $src = $m[1];
- // Word 导出的是相对路径
if (!str_starts_with($src, 'http')) {
- $localImg = $tmpDir . '/' . ltrim($src, '/');
+ $localImg = $tmpDir . '/' . ltrim($src, './');
if (is_file($localImg)) {
$ossUrl = $uploadService->uploadLocalFile([
- 'path' => $localImg,
+ 'path' => $localImg,
'scene' => 'desc'
]);
- return preg_replace('/src="[^"]+"/', 'src="' . $ossUrl . '"', $matches[0]);
+ return preg_replace('/src="[^"]+"/', 'src="'.$ossUrl['file_url'].'"', $m[0]);
}
}
-
- return $matches[0];
+ return $m[0];
},
$html
);
- // 6. 清理临时目录
- $this->deleteDir($tmpDir);
+ // 2️⃣ 关键:HTML 清洗(适配 wangEditor)
+ $html = $this->cleanWordHtmlForWangEditor($html);
- return trim($html);
+ return $html;
}
function deleteDir(string $dir): void
@@ -325,28 +312,44 @@ class SkuController extends BaseController
foreach (scandir($dir) as $file) {
if ($file === '.' || $file === '..') continue;
$path = $dir . '/' . $file;
- is_dir($path) ? deleteDir($path) : @unlink($path);
+ is_dir($path) ? $this->deleteDir($path) : @unlink($path);
}
@rmdir($dir);
}
- function cleanWordHtml(string $html): string
+ function cleanWordHtmlForWangEditor(string $html): string
{
- // 移除 Office 命名空间、样式
- $html = preg_replace('/\s*mso-[^:]+:[^;"]+;?/i', '', $html);
- $html = preg_replace('/\s*class="[^"]*"/i', '', $html);
- $html = preg_replace('/\s*style="[^"]*"/i', '', $html);
+ // 1. 移除 Word 专属标签
+ $html = preg_replace('/.*?<\/o:p>/is', '', $html);
+ $html = preg_replace('/<\/?xml[^>]*>/i', '', $html);
+ $html = preg_replace('/<\/?v:[^>]*>/i', '', $html);
- // 移除多余标签
- $html = preg_replace('/<(\/?)(html|head|meta|link|span|font|xml|o:p)[^>]*>/i', '', $html);
+ // 2. 移除 class / style
+ $html = preg_replace('/\sclass="[^"]*"/i', '', $html);
+ $html = preg_replace('/\sstyle="[^"]*"/i', '', $html);
- // 清理空段落
- $html = preg_replace('/\s*<\/p>/i', '', $html);
+ // 3. 清理 span(保留内容)
+ while (preg_match('/]*>(.*?)<\/span>/is', $html)) {
+ $html = preg_replace('/]*>(.*?)<\/span>/is', '$1', $html);
+ }
- // 规范段落
- $html = str_replace(['', '
'], ["", "
\n"], $html);
+ // 4. 转换 div → p
+ $html = preg_replace('/]*>/i', '
', $html);
+ $html = preg_replace('/<\/div>/i', '
', $html);
- return $html;
+ // 5. img 只保留 src
+ $html = preg_replace('/
![]()
]*src="([^"]+)"[^>]*>/i', '

', $html);
+
+ // 6. table 清洗
+ $html = preg_replace('/
]*>/i', '', $html);
+ $html = preg_replace('/| ]*>/i', ' | ', $html);
+ $html = preg_replace('/ | ]*>/i', ' | ', $html);
+
+ // 7. 去除多余空白
+ $html = preg_replace('/\s+/u', ' ', $html);
+ $html = str_replace(['', ' '], '', $html);
+
+ return trim($html);
}
|