You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.9 KiB
89 lines
2.9 KiB
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,
|
|
}
|
|
|