吉林码农的"文档导入插件大冒险":从FCKEditor到全能粘贴王的逆袭之路
第一章:客户爸爸的"核弹级"需求
"老王啊,我们新闻编辑器要加个功能,能直接导入Word/Excel/PPT/PDF,还要保留所有样式和公式!"客户叼着烟,云淡风轻地说。
我差点把咖啡喷在键盘上:“您说的这个功能,怕是要造个火箭啊!”
"预算嘛…680块,你看着办。"客户说完就挂了电话,留下我在风中凌乱。
第二章:开源世界的"寻宝之旅"
我立马打开GitHub,开始了"寻宝"之旅:
- Mammoth.js:Word转HTML不错,但公式支持差
- Docx.js:纯前端解析,性能感人
- Apache POI:Java项目,PHP用不了
- Pandoc:功能强大,但集成复杂
就在我快绝望时,在某个技术论坛的角落发现了"OfficeParser"这个宝藏项目——虽然不完美,但至少是个好的起点!
第三章:前端改造:Vue2里的"插件魔术"
3.1 修改FCKEditor配置
// fckeditor_custom.js
FCKConfig.ToolbarSets["Default"] = [
['Source','-','Paste','PasteFromWord','-','OfficeImport'], // 新增按钮
// ...其他配置
];
FCKConfig.PluginsPath = '/plugins/';
FCKConfig.Plugins.Add('officeimport', 'en,zh-cn');
3.2 创建Vue插件组件
export default {
data() {
return {
previewHtml: '',
fileType: ''
}
},
methods: {
triggerFileInput() {
this.$refs.fileInput.click();
},
async handleFileChange(e) {
const file = e.target.files[0];
if (!file) return;
this.fileType = file.name.split('.').pop().toLowerCase();
const formData = new FormData();
formData.append('file', file);
try {
const res = await this.$http.post('/api/office/parse', formData);
this.previewHtml = this.processContent(res.data.html);
} catch (err) {
console.error('解析失败:', err);
}
},
processContent(html) {
// 处理微信公众号特殊样式
html = html.replace(/font-family: "Microsoft YaHei";/g, '');
// 处理表格样式
html = html.replace(/<table>/g, '<table class="office-table">');
return html;
},
insertToEditor() {
const editor = window.FCKeditorAPI.GetInstance("editor_content");
editor.InsertHtml(this.previewHtml);
this.$refs.fileInput.value = '';
this.previewHtml = '';
}
}
}
第四章:后端开发:PHP的"文档解析大作战"
4.1 主解析控制器
ossClient = new \OSS\OssClient(
'your-access-key',
'your-secret-key',
'your-endpoint'
);
}
public function parse() {
if (!isset($_FILES['file'])) {
throw new Exception('未上传文件');
}
$file = $_FILES['file'];
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
try {
$parser = ParserFactory::create($extension);
$tempPath = tempnam(sys_get_temp_dir(), 'office_');
move_uploaded_file($file['tmp_name'], $tempPath);
$result = $parser->parse($tempPath);
unlink($tempPath);
// 处理图片上传
$html = $this->processImages($result['html'], $extension);
// 处理Latex公式
$html = $this->convertLatex($html);
echo json_encode([
'success' => true,
'html' => $html,
'message' => '解析成功'
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
}
private function processImages($html, $fileType) {
$dom = new DOMDocument();
@$dom->loadHTML('' . $html);
$images = $dom->getElementsByTagName('img');
foreach ($images as $img) {
if (preg_match('/data:image\/([^;]+);base64,/', $img->getAttribute('src'), $matches)) {
$imageData = base64_decode(preg_replace('/^data:image\/\w+;base64,/', '', $img->getAttribute('src')));
$imageName = uniqid() . '.' . $matches[1];
// 上传到OSS
$ossPath = 'office_imports/' . date('Ymd') . '/' . $imageName;
$this->ossClient->putObject('your-bucket', $ossPath, $imageData);
// 替换为OSS链接
$img->setAttribute('src', 'https://your-bucket.oss-cn-region.aliyuncs.com/' . $ossPath);
}
}
return $dom->saveHTML();
}
private function convertLatex($html) {
// 这里简化处理,实际项目中应该使用专业的Latex解析库
return preg_replace_callback('/\\\(.*?)\\\)/', function($matches) {
// 简单替换为MathML示例
$latex = trim($matches[1]);
return '' .
'' . htmlspecialchars($latex) . '' .
'';
}, $html);
}
}
$controller = new OfficeImportController();
$controller->parse();
4.2 解析器工厂类
'Word文档标题这里是示例内容',
'images' => []
];
}
}
class ExcelParser {
public function parse($filePath) {
// 实际项目中应该使用PHPExcel等库
return [
'html' => '单元格1单元格2',
'images' => []
];
}
}
第五章:部署与测试:从"爆炸"到"完美"
5.1 部署过程
- 上传插件文件到
/plugins/officeimport/目录 - 配置阿里云OSS权限
- 修改FCKEditor配置文件
- 重启PHP服务
5.2 测试用例
// 测试脚本
describe('OfficeImport Plugin', () => {
it('should import Word document', () => {
const file = new File(['Test'], 'test.docx');
// 模拟文件上传和解析过程
// 验证HTML结构和样式保留
});
it('should convert Latex formulas', () => {
const html = 'E=mc^2';
const processed = processContent(html);
expect(processed).toContain('
815

被折叠的 条评论
为什么被折叠?



