12 changed files with 389 additions and 345 deletions
-
2src/main.js
-
263src/utils/filePreview.js
-
26src/views/modules/qc/FQCResultEntry.vue
-
45src/views/modules/qc/IPQCResultEntry.vue
-
84src/views/modules/qc/IQCFileTable.vue
-
35src/views/modules/qc/IQCResultEntry.vue
-
83src/views/modules/qc/OQCResultEntry.vue
-
42src/views/modules/qc/QCReportFileTable.vue
-
41src/views/modules/qc/sopListComponent.vue
-
42src/views/modules/shopOrder/shopOrder/shopNotice.vue
-
26src/views/modules/yieldReport/com_process_inspection.vue
-
45src/views/modules/yieldReport/com_produce_report_normal.vue
@ -0,0 +1,263 @@ |
|||
/** |
|||
* 文件预览工具类 |
|||
* 支持图片、视频、PDF、TXT、Excel、Word、PPT等格式的预览 |
|||
*/ |
|||
import XLSX from 'xlsx' |
|||
|
|||
// 文件类型分类
|
|||
const FILE_TYPES = { |
|||
image: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'], |
|||
video: ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm'], |
|||
pdf: ['pdf'], |
|||
txt: ['txt', 'log', 'json', 'xml', 'csv'], |
|||
excel: ['xls', 'xlsx'], |
|||
word: ['doc', 'docx'], |
|||
ppt: ['ppt', 'pptx'] |
|||
} |
|||
|
|||
/** |
|||
* 获取文件后缀 |
|||
*/ |
|||
export function getFileSuffix(fileName) { |
|||
if (!fileName || !fileName.includes('.')) return '' |
|||
return fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase() |
|||
} |
|||
|
|||
/** |
|||
* 获取文件类型 |
|||
*/ |
|||
export function getFileType(fileName) { |
|||
const suffix = getFileSuffix(fileName) |
|||
for (const [type, extensions] of Object.entries(FILE_TYPES)) { |
|||
if (extensions.includes(suffix)) return type |
|||
} |
|||
return 'unknown' |
|||
} |
|||
|
|||
/** |
|||
* 获取MIME类型 |
|||
*/ |
|||
export function getMimeType(suffix) { |
|||
const mimeMap = { |
|||
// 图片
|
|||
jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif', bmp: 'image/bmp', webp: 'image/webp', |
|||
// 视频
|
|||
mp4: 'video/mp4', avi: 'video/x-msvideo', mov: 'video/quicktime', wmv: 'video/x-ms-wmv', flv: 'video/x-flv', webm: 'video/webm', |
|||
// 文档
|
|||
pdf: 'application/pdf', |
|||
txt: 'text/plain', log: 'text/plain', json: 'application/json', xml: 'application/xml', csv: 'text/csv', |
|||
// Office
|
|||
xls: 'application/vnd.ms-excel', |
|||
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', |
|||
doc: 'application/msword', |
|||
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', |
|||
ppt: 'application/vnd.ms-powerpoint', |
|||
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' |
|||
} |
|||
return mimeMap[suffix] || 'application/octet-stream' |
|||
} |
|||
|
|||
/** |
|||
* 将Blob转换为ArrayBuffer |
|||
* @param {Blob} blob - Blob对象 |
|||
* @returns {Promise<ArrayBuffer>} |
|||
*/ |
|||
export function blobToArrayBuffer(blob) { |
|||
return new Promise((resolve, reject) => { |
|||
const reader = new FileReader() |
|||
reader.onload = () => resolve(reader.result) |
|||
reader.onerror = () => reject(new Error('Blob转换失败')) |
|||
reader.readAsArrayBuffer(blob) |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 预览Excel文件 |
|||
* @param {ArrayBuffer} arrayBuffer - 文件数据(ArrayBuffer格式) |
|||
* @param {String} fileName - 文件名 |
|||
*/ |
|||
export function previewExcel(arrayBuffer, fileName) { |
|||
try { |
|||
const workbook = XLSX.read(arrayBuffer, { type: 'array' }) |
|||
const sheetName = workbook.SheetNames[0] |
|||
const worksheet = workbook.Sheets[sheetName] |
|||
const htmlString = XLSX.utils.sheet_to_html(worksheet, { editable: false }) |
|||
|
|||
// 预先生成所有sheet的HTML
|
|||
const sheetsHtml = workbook.SheetNames.map(name => { |
|||
return XLSX.utils.sheet_to_html(workbook.Sheets[name], { editable: false }) |
|||
}) |
|||
|
|||
// 创建预览窗口
|
|||
const previewWindow = window.open('', '_blank') |
|||
if (!previewWindow) { |
|||
throw new Error('无法打开预览窗口,请检查浏览器是否阻止了弹出窗口') |
|||
} |
|||
|
|||
previewWindow.document.write(`
|
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Excel预览 - ${fileName}</title> |
|||
<style> |
|||
body { font-family: Arial, sans-serif; padding: 20px; background: #f5f5f5; } |
|||
.header { background: #409EFF; color: white; padding: 15px 20px; margin: -20px -20px 20px -20px; } |
|||
.header h2 { margin: 0; font-size: 18px; } |
|||
.sheet-tabs { background: #fff; padding: 10px; margin-bottom: 10px; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } |
|||
.sheet-tab { display: inline-block; padding: 8px 16px; margin-right: 5px; background: #f0f0f0; border-radius: 4px; cursor: pointer; } |
|||
.sheet-tab.active { background: #409EFF; color: white; } |
|||
.table-container { background: white; padding: 15px; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); overflow: auto; max-height: calc(100vh - 180px); } |
|||
table { border-collapse: collapse; width: 100%; } |
|||
th, td { border: 1px solid #ddd; padding: 8px 12px; text-align: left; white-space: nowrap; } |
|||
th { background: #f5f7fa; font-weight: 600; position: sticky; top: 0; } |
|||
tr:nth-child(even) { background: #fafafa; } |
|||
tr:hover { background: #f0f7ff; } |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div class="header"> |
|||
<h2>Excel预览 - ${fileName}</h2> |
|||
</div> |
|||
<div class="sheet-tabs"> |
|||
${workbook.SheetNames.map((name, index) => |
|||
`<span class="sheet-tab ${index === 0 ? 'active' : ''}" onclick="showSheet(${index})">${name}</span>` |
|||
).join('')} |
|||
</div> |
|||
<div class="table-container" id="tableContainer"> |
|||
${htmlString} |
|||
</div> |
|||
<script> |
|||
var sheets = ${JSON.stringify(sheetsHtml)}; |
|||
function showSheet(index) { |
|||
document.getElementById('tableContainer').innerHTML = sheets[index]; |
|||
var tabs = document.querySelectorAll('.sheet-tab'); |
|||
tabs.forEach(function(tab, i) { |
|||
tab.className = 'sheet-tab' + (i === index ? ' active' : ''); |
|||
}); |
|||
} |
|||
<\/script> |
|||
</body> |
|||
</html> |
|||
`)
|
|||
previewWindow.document.close() |
|||
return true |
|||
} catch (error) { |
|||
console.error('Excel预览失败:', error) |
|||
return false |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 预览Word文件(下载后打开) |
|||
* @param {Blob} blobData - 文件数据(Blob格式) |
|||
* @param {String} fileName - 文件名 |
|||
*/ |
|||
export function previewWord(blobData, fileName) { |
|||
// 对于Word文件,直接下载让用户用本地软件打开
|
|||
const url = URL.createObjectURL(blobData) |
|||
|
|||
// 创建下载链接
|
|||
const link = document.createElement('a') |
|||
link.href = url |
|||
link.download = fileName |
|||
link.click() |
|||
|
|||
URL.revokeObjectURL(url) |
|||
return true |
|||
} |
|||
|
|||
/** |
|||
* 预览PPT文件(下载后打开) |
|||
* @param {Blob} blobData - 文件数据(Blob格式) |
|||
* @param {String} fileName - 文件名 |
|||
*/ |
|||
export function previewPPT(blobData, fileName) { |
|||
// 对于PPT文件,直接下载让用户用本地软件打开
|
|||
const url = URL.createObjectURL(blobData) |
|||
|
|||
// 创建下载链接
|
|||
const link = document.createElement('a') |
|||
link.href = url |
|||
link.download = fileName |
|||
link.click() |
|||
|
|||
URL.revokeObjectURL(url) |
|||
return true |
|||
} |
|||
|
|||
/** |
|||
* 通用文件预览方法 |
|||
* @param {ArrayBuffer|Blob} data - 文件数据(可能是Blob或ArrayBuffer) |
|||
* @param {String} fileName - 文件名 |
|||
* @returns {Promise} 预览结果 |
|||
*/ |
|||
export async function previewFile(data, fileName) { |
|||
const suffix = getFileSuffix(fileName) |
|||
const fileType = getFileType(fileName) |
|||
const mimeType = getMimeType(suffix) |
|||
|
|||
try { |
|||
// 确保data是正确的格式
|
|||
let blobData = data |
|||
let arrayBufferData = null |
|||
|
|||
// 如果data是Blob,保存引用;如果不是,创建Blob
|
|||
if (!(data instanceof Blob)) { |
|||
blobData = new Blob([data], { type: mimeType }) |
|||
} |
|||
|
|||
switch (fileType) { |
|||
case 'excel': |
|||
// Excel文件需要ArrayBuffer格式
|
|||
arrayBufferData = await blobToArrayBuffer(blobData) |
|||
if (previewExcel(arrayBufferData, fileName)) { |
|||
return { success: true, type: 'excel' } |
|||
} else { |
|||
throw new Error('Excel预览失败') |
|||
} |
|||
|
|||
case 'word': |
|||
// Word文件下载后打开
|
|||
previewWord(blobData, fileName) |
|||
return { success: true, type: 'word', message: '文件已下载,请使用本地软件打开' } |
|||
|
|||
case 'ppt': |
|||
// PPT文件下载后打开
|
|||
previewPPT(blobData, fileName) |
|||
return { success: true, type: 'ppt', message: '文件已下载,请使用本地软件打开' } |
|||
|
|||
case 'image': |
|||
case 'video': |
|||
case 'pdf': |
|||
case 'txt': |
|||
// 这些类型浏览器原生支持,创建Blob URL后打开
|
|||
const fileURL = URL.createObjectURL(blobData) |
|||
window.open(fileURL, '_blank') |
|||
return { success: true, type: fileType } |
|||
|
|||
default: |
|||
// 未知类型,下载处理
|
|||
const downloadUrl = URL.createObjectURL(blobData) |
|||
const link = document.createElement('a') |
|||
link.href = downloadUrl |
|||
link.download = fileName |
|||
link.click() |
|||
URL.revokeObjectURL(downloadUrl) |
|||
return { success: true, type: 'download', message: '文件已下载' } |
|||
} |
|||
} catch (error) { |
|||
console.error('文件预览错误:', error) |
|||
throw error |
|||
} |
|||
} |
|||
|
|||
export default { |
|||
getFileSuffix, |
|||
getFileType, |
|||
getMimeType, |
|||
previewExcel, |
|||
previewWord, |
|||
previewPPT, |
|||
previewFile |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue