【代码分享】【本地表JS宏】将Base64编码的图片插入到WPS表格指定单元格位置
标题写的很清楚,用到的朋友可以直接拿去,不想写太多文字了今天搞累了。。。
function test() {Console.clear()
图片base64 = 'data:image/png;base64,iVBORw0KGgo。。。'
InsertBase64ImageToCell(图片base64, Range("e4"),300,200)
}
/**by theMath404 & 各种AI 花了好几个小时!
* 在 WPS12.1.0.25860 本地表格的JSA 能成功运行,后续版本自行测试
* 引用还望注明出处,谁说AI写代码很强了?我都是一把屎一把尿搞出来的!
* 最后编辑:2026.04.29
* 【功能说明】将Base64编码的图片插入到WPS表格指定单元格位置(纯原生兼容版)
*/
function InsertBase64ImageToCell(base64Str, targetCell, imgWidth=-1, imgHeight=-1, placement=xlMoveAndSize) {
Console.log("==================== 开始执行图片插入 ====================");
try {
if (!base64Str || typeof base64Str !== "string") {
throw new Error("参数错误:base64Str不能为空且必须为字符串类型");
}
if (!targetCell || typeof targetCell.Left === "undefined" || typeof targetCell.Top === "undefined" || typeof targetCell.Address !== "function") {
throw new Error("参数错误:targetCell必须为Range对象(例如Range('B2')),请勿直接传单元格地址字符串");
}
if (imgWidth !== -1 && (typeof imgWidth !== "number" || imgWidth <= 0)) {
throw new Error("参数错误:imgWidth必须为正整数或-1");
}
if (imgHeight !== -1 && (typeof imgHeight !== "number" || imgHeight <= 0)) {
throw new Error("参数错误:imgHeight必须为正整数或-1");
}
// ========== 2. 处理Base64前缀 ==========
if (base64Data.length === 0) {
throw new Error("Base64内容为空,可能是格式错误");
}
// ========== 3. 生成两种格式的临时文件路径(已修复斜杠不一致问题) ==========
// 第一步:先把临时目录所有斜杠统一转成反斜杠,再去除末尾的斜杠,最后补一个反斜杠,确保目录格式100%纯反斜杠
const tempDir = Env.GetTempPath().replace(/\//g, "\\").replace(/\\+$/, "") + "\\";
const fileName = "temp_img_" + Date.now() + ".png";
// writePath:全程纯反斜杠,用于写入、删除
const writePath = tempDir + fileName;
// readPath:全程纯正斜杠,仅用于AddPicture
const readPath = tempDir.replace(/\\/g, "/") + fileName;
// ========== 4. 直接Base64转二进制字符串(恢复原自定义函数,适配WPS环境) ==========
const binaryStr = base64ToBinary(base64Data);
if (binaryStr.length < 100) {
throw new Error("Base64解析失败,内容过短,可能是Base64格式错误");
}
// ========== 5. 写入临时文件(核心修复:使用writeAsBinaryString纯二进制写入,严格遵循官方API) ==========
FileSystem.writeAsBinaryString(writePath, binaryStr);
// ========== 6. 插入图片到工作表(用readPath正斜杠路径) ==========
const msoTrue = -1;
const msoFalse = 0;
const shape = targetCell.Worksheet.Shapes.AddPicture( readPath,
msoFalse, msoTrue,targetCell.Left, targetCell.Top,imgWidth, imgHeight
);
if (!shape) {
throw new Error("Shapes.AddPicture调用失败,未返回Shape对象(可能是路径格式错误或文件损坏)");
}
// ========== 7. 后续设置与清理(用writePath反斜杠路径删除) ==========
shape.Placement = placement;
// 删除临时文件
try {
// 修复:使用官方API FileSystem.Remove 替代 Kill
FileSystem.Remove(writePath);
Console.log("✅ 临时文件已删除");
} catch(e) {
// 修复:使用 Console.log 替代不支持的 Console.warn
Console.log("⚠️ 临时文件删除失败,路径:" + writePath);
}
Console.log("==================== 图片插入全部完成 ====================");
return shape;
} catch (err) {
Console.log(`❌ 执行失败,错误位置:${err.stack || '未知位置'}`);
Console.log(`❌ 错误信息:${err.message}`);
Console.log("==================== 执行异常终止 ====================");
return null;
}
/**
* 辅助函数:Base64直接转二进制字符串(适配WPS写入,无需数组中转)
* @param {string} base64 - 无前缀的Base64字符串
* @returns {string} 二进制字符串
*/
function base64ToBinary(base64) {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let binary = "";
let i = 0;
base64 = base64.replace(/\s/g, "").replace(/=+$/, ""); // 去除空白和填充符
while (i < base64.length) {
const enc1 = chars.indexOf(base64.charAt(i++));
const enc2 = chars.indexOf(base64.charAt(i++));
const enc3 = i < base64.length ? chars.indexOf(base64.charAt(i++)) : -1;
const enc4 = i < base64.length ? chars.indexOf(base64.charAt(i++)) : -1;
if (enc1 === -1 || enc2 === -1) {
throw new Error(`Base64解析错误,位置${i}存在非法字符:${base64.charAt(i-1)}`);
}
// 直接拼接二进制字符,无需数组中转,减少编码问题
binary += String.fromCharCode((enc1 << 2) | (enc2 >> 4));
if (enc3 !== -1) binary += String.fromCharCode(((enc2 & 15) << 4) | (enc3 >> 2));
if (enc4 !== -1) binary += String.fromCharCode(((enc3 & 3) << 6) | enc4);
}
return binary;
}
}
Lv.2潜力创作者