const { imageSize } = require('image-size'); const cheerio = require('cheerio'); const superagent = require('superagent'); const htmlDocx = require('html-docx-js'); /** * 将Blob对象转换为Buffer * @param {Blob} blob - 要转换的Blob对象\ * @returns {Buffer} - 转换后的Buffer对象 * @throws {Error} - 如果转换失败,将抛出错误 */ async function blobToBuffer(blob) { // 将Blob转换成ArrayBuffer const arrayBuffer = await blob.arrayBuffer(); // 使用Node.js的Buffer.from方法从ArrayBuffer创建Buffer const buffer = Buffer.from(arrayBuffer); return buffer; } /** * 下载html里的网络图片并转换成base64格式 * @param {String} htmlContent * @return {String} - 处理后的HTML内容 * @throws {Error} - 如果下载图片失败,将抛出错误 */ async function preprocessHTMLContentWithBase64Images(htmlContent) { if (!htmlContent) { return ''; } const $ = cheerio.load(htmlContent); const imgPromises = []; $('img').each(function (index, element) { const imgTag = $(element); let src = imgTag.attr('src'); if (src && (src.startsWith('http://') || src.startsWith('https://'))) { const promise = superagent.get(src) .responseType('arraybuffer') .then(response => { const imageBuffer = Buffer.from(response.body, 'binary'); const base64Image = imageBuffer.toString('base64'); const dimensions = imageSize(imageBuffer); let mimeType = 'image/png'; // 默认值 const contentTypeHeader = response.headers['content-type']; if (contentTypeHeader) { mimeType = contentTypeHeader.split(';')[0]; } imgTag.attr('src', `data:${mimeType};base64,${base64Image}`); // 如果图片宽度大于620px,则调整宽度为620px,并按比例缩放高度 if (dimensions.width > 620) { const ratio = dimensions.width / dimensions.height; imgTag.attr('width', '620'); imgTag.attr('height', Math.round(620 / ratio)); } }) .catch(error => { console.error(`Error fetching image ${src} with superagent:`, error.message); }); imgPromises.push(promise); } }); await Promise.all(imgPromises); return $.html(); } /** * 转换html内容为docx格式 * @param {String} htmlContent * @return {Buffer} - 转换后的docx格式Buffer * @throws {Error} - 如果转换失败,将抛出错误 */ async function convertHTMLToDOCX(htmlContent) { const processedHtml = await preprocessHTMLContentWithBase64Images(htmlContent); const docxBlob = htmlDocx.asBlob(processedHtml); const docxBuffer = blobToBuffer(docxBlob); return docxBuffer; } module.exports = { blobToBuffer, preprocessHTMLContentWithBase64Images, convertHTMLToDOCX, }