/**
* HTML Generator Utility
* 用于生成幻灯片的 HTML 内容
*/
/**
* 生成幻灯片的 HTML 内容
* @param {Object} slideData - 幻灯片数据
* @param {number} slideIndex - 幻灯片索引
* @param {Object} options - 渲染选项
* @returns {string} HTML 字符串
*/
export function generateSlideHTML(slideData, slideIndex = 0, options = {}) {
const {
width = 1000,
height = 562,
backgroundColor = '#ffffff',
scale = 1
} = options;
if (!slideData || !slideData.slides || !slideData.slides[slideIndex]) {
throw new Error(`Invalid slide data or slide index: ${slideIndex}`);
}
const slide = slideData.slides[slideIndex];
const slideBackground = slide.background || backgroundColor;
// 生成元素的 HTML
const elementsHTML = generateElementsHTML(slide.elements || [], { width, height, scale });
return `
Slide ${slideIndex + 1}
${elementsHTML}
`.trim();
}
/**
* 生成元素的 HTML
* @param {Array} elements - 元素数组
* @param {Object} options - 渲染选项
* @returns {string} 元素 HTML 字符串
*/
function generateElementsHTML(elements, options = {}) {
if (!Array.isArray(elements)) {
return '';
}
return elements.map(element => {
try {
return generateElementHTML(element, options);
} catch (error) {
console.warn(`Failed to generate HTML for element:`, element, error);
return '';
}
}).join('\n');
}
/**
* 生成单个元素的 HTML
* @param {Object} element - 元素数据
* @param {Object} options - 渲染选项
* @returns {string} 元素 HTML 字符串
*/
function generateElementHTML(element, options = {}) {
if (!element || typeof element !== 'object') {
return '';
}
const {
type,
left = 0,
top = 0,
width = 100,
height = 100,
rotate = 0,
opacity = 1
} = element;
const baseStyle = `
left: ${left}px;
top: ${top}px;
width: ${width}px;
height: ${height}px;
transform: rotate(${rotate}deg);
opacity: ${opacity};
`;
switch (type) {
case 'text':
return generateTextElementHTML(element, baseStyle);
case 'image':
return generateImageElementHTML(element, baseStyle);
case 'shape':
return generateShapeElementHTML(element, baseStyle);
case 'line':
return generateLineElementHTML(element, baseStyle);
case 'chart':
return generateChartElementHTML(element, baseStyle);
case 'table':
return generateTableElementHTML(element, baseStyle);
default:
console.warn(`Unknown element type: ${type}`);
return '';
}
}
/**
* 生成文本元素 HTML
*/
function generateTextElementHTML(element, baseStyle) {
const {
content = '',
fontSize = 14,
fontFamily = 'Arial',
color = '#000000',
fontWeight = 'normal',
fontStyle = 'normal',
textDecoration = 'none',
textAlign = 'left',
lineHeight = 1.2
} = element;
const textStyle = `
font-size: ${fontSize}px;
font-family: ${fontFamily};
color: ${color};
font-weight: ${fontWeight};
font-style: ${fontStyle};
text-decoration: ${textDecoration};
text-align: ${textAlign};
line-height: ${lineHeight};
`;
return `
${escapeHtml(content)}
`;
}
/**
* 生成图片元素 HTML
*/
function generateImageElementHTML(element, baseStyle) {
const { src = '', alt = '' } = element;
if (!src) {
return `
`;
}
return `
`;
}
/**
* 生成形状元素 HTML
*/
function generateShapeElementHTML(element, baseStyle) {
const {
fill = '#ffffff',
stroke = '#000000',
strokeWidth = 1,
borderRadius = 0
} = element;
const shapeStyle = `
background: ${fill};
border: ${strokeWidth}px solid ${stroke};
border-radius: ${borderRadius}px;
`;
return `
`;
}
/**
* 生成线条元素 HTML
*/
function generateLineElementHTML(element, baseStyle) {
const {
stroke = '#000000',
strokeWidth = 2
} = element;
const lineStyle = `
background: ${stroke};
height: ${strokeWidth}px;
color: ${stroke};
`;
return `
`;
}
/**
* 生成图表元素 HTML
*/
function generateChartElementHTML(element, baseStyle) {
// 简化的图表渲染,实际项目中可能需要更复杂的图表库
return `
`;
}
/**
* 生成表格元素 HTML
*/
function generateTableElementHTML(element, baseStyle) {
const { data = [] } = element;
if (!Array.isArray(data) || data.length === 0) {
return `
`;
}
const tableHTML = data.map(row => {
if (!Array.isArray(row)) return '';
const cellsHTML = row.map(cell => `${escapeHtml(String(cell))} | `).join('');
return `${cellsHTML}
`;
}).join('');
return `
`;
}
/**
* HTML 转义函数
* @param {string} text - 需要转义的文本
* @returns {string} 转义后的文本
*/
function escapeHtml(text) {
if (typeof text !== 'string') {
return String(text);
}
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
/**
* 生成完整的 PPT HTML(包含所有幻灯片)
* @param {Object} pptData - PPT 数据
* @param {Object} options - 渲染选项
* @returns {string} 完整的 HTML 字符串
*/
export function generatePPTHTML(pptData, options = {}) {
if (!pptData || !pptData.slides || !Array.isArray(pptData.slides)) {
throw new Error('Invalid PPT data');
}
const { width = 1000, height = 562 } = options;
const slidesHTML = pptData.slides.map((slide, index) => {
try {
return generateSlideHTML(pptData, index, options);
} catch (error) {
console.warn(`Failed to generate HTML for slide ${index}:`, error);
return `
幻灯片 ${index + 1} 渲染失败
`;
}
}).join('\n\n');
return `
PPT Preview
${slidesHTML}
`.trim();
}
export default {
generateSlideHTML,
generatePPTHTML
};