更新记录

0.1.0(2026-10-01)

首版:WPS DISPIMG跨工作表按业务列命名导出图片、重名编号、空名称回退及CSV清单。提供双工作表示例文件。阿里云Node 16真实客户端调用及三图字节校验通过。原文件和导出ZIP各限1MiB。


平台兼容性

云端兼容性

支付宝云 腾讯云 阿里云
× × √

WPS DISPIMG 图片按业务列命名导出

给已有 uniCloud 项目的开发者使用:读取 WPS .xlsx 中的 DISPIMG 单元格图片,按 SKU、商品编号等业务列命名,返回图片 ZIP 和 CSV 清单。支持跨工作表、重名编号和空名称地址回退,保留图片原始字节。

适用范围:小文件的 WPS DISPIMG 图片。 不处理 Excel 浮动图片、外部图片链接、旧版 .xls 或加密工作簿。这是云函数插件,需要开发者接入自己的页面;没有独立桌面应用或现成在线转换网站。

接入

  1. 在已有 uni-app 项目中导入插件,关联自己的阿里云 uniCloud 服务空间。
  2. 在 HBuilderX 中将 pl-wps-dispimg-export 云函数上传部署,等待云端依赖安装完成。
  3. 从客户端通过 uniCloud.callFunction 调用。不要开启 HTTP URL 化或用云端控制台调用替代客户端调用。
const { result } = await uniCloud.callFunction({
  name: 'pl-wps-dispimg-export',
  data: {
    xlsxBase64,       // 原始 xlsx 文件的 Base64,不带 data: 前缀
    imageColumn: 'B', // DISPIMG 图片所在列
    nameColumn: 'A'   // 用作文件名的业务列
  }
});
if (!result.ok) throw new Error(result.error.message);
// result.zipBase64: 输出 ZIP 的 Base64
// result.exported / unmatched / blankNames: 导出及异常计数
// result.report: 工作表、单元格与输出文件的对应关系

浏览器中的文件可用 FileReader.readAsDataURL(file) 读取,并取第一个逗号之后的 Base64。ZIP 保存方式由接入页面决定。

下面是文件选择到 ZIP 下载的完整 H5 接入示例。前提是当前页面已初始化官方 uniCloud 客户端 SDK,并已在关联的阿里云空间部署此函数。默认图片列 B、命名列 A;页面会显示导出计数及清单。仅提供 H5 接入代码,未新增云端实测,不代表 App 或小程序兼容。

<input id="dispimg-file" type="file" accept=".xlsx">
<button id="dispimg-export" type="button">导出 ZIP(图片 B 列,命名 A 列)</button>
<pre id="dispimg-status" role="status">请选择不超过 1 MiB 的 .xlsx 文件。</pre>
<script>
const dispimgLimit = 1024 * 1024;
const dispimgFile = document.getElementById('dispimg-file');
const dispimgButton = document.getElementById('dispimg-export');
const dispimgStatus = document.getElementById('dispimg-status');
let dispimgBusy = false;
function dispimgReadFile(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(String(reader.result).split(',')[1]);
    reader.onerror = () => reject(new Error('文件读取失败,请重新选择文件。'));
    reader.onabort = () => reject(new Error('文件读取已取消。'));
    reader.readAsDataURL(file);
  });
}
async function dispimgExportZip(file, sdk) {
  if (!file) throw new Error('未选择文件。');
  if (!/\.xlsx$/i.test(file.name)) throw new Error('仅支持 .xlsx 文件。');
  if (!file.size || file.size > dispimgLimit) throw new Error('文件须为 1 MiB 以内的非空 .xlsx。');
  if (!sdk || typeof sdk.callFunction !== 'function') throw new Error('请先初始化官方 uniCloud SDK。');
  const xlsxBase64 = await dispimgReadFile(file);
  const { result } = await sdk.callFunction({
    name: 'pl-wps-dispimg-export', data: { xlsxBase64, imageColumn: 'B', nameColumn: 'A' }
  });
  if (!result || result.ok !== true) throw new Error(result?.error?.message || '云函数未成功返回。');
  if (typeof result.zipBase64 !== 'string' || !result.zipBase64.length) throw new Error('未返回 ZIP。');
  if (result.zipBase64.length > Math.ceil(dispimgLimit / 3) * 4) throw new Error('ZIP 超过 1 MiB。');
  const binary = atob(result.zipBase64);
  if (!binary.length || binary.length > dispimgLimit) throw new Error('ZIP 为空或超过 1 MiB。');
  const zip = new Blob([Uint8Array.from(binary, ch => ch.charCodeAt(0))], { type: 'application/zip' });
  return { result, zip };
}
dispimgFile.addEventListener('cancel', () => {
  if (!dispimgBusy) dispimgStatus.textContent = '已取消选择文件;尚未发起云调用。';
});
dispimgButton.addEventListener('click', async () => {
  if (dispimgBusy) return;
  if (!dispimgFile.files[0]) { dispimgStatus.textContent = '请先选择 .xlsx 文件。'; return; }
  dispimgBusy = true; dispimgButton.disabled = true; dispimgFile.disabled = true;
  dispimgStatus.textContent = '正在读取文件并调用云函数……';
  let objectUrl, link;
  try {
    const file = dispimgFile.files[0];
    const { result, zip } = await dispimgExportZip(file, typeof uniCloud === 'undefined' ? null : uniCloud);
    dispimgStatus.textContent = JSON.stringify({
      exported: result.exported ?? '未提供', unmatched: result.unmatched ?? '未提供',
      blankNames: result.blankNames ?? '未提供', report: result.report ?? '未提供'
    }, null, 2);
    objectUrl = URL.createObjectURL(zip);
    link = document.createElement('a'); link.href = objectUrl;
    link.download = file.name.replace(/\.xlsx$/i, '') + '-images.zip';
    document.body(link); link.click();
  } catch (error) {
    dispimgStatus.textContent = '导出失败:' + (error?.message || String(error));
  } finally {
    link?.remove();
    if (objectUrl) setTimeout(() => URL.revokeObjectURL(objectUrl), 1000);
    dispimgBusy = false; dispimgButton.disabled = false; dispimgFile.disabled = false;
  }
});
</script>

先用样例验证

包内 examples/sample-wps.xlsx 有两个工作表。图片列为 B,命名列为 A;应导出 Beta_Blue.png、Alpha_Red.png、Alpha_Red_2.png 和 导出清单.csv。建议先使用平台试用,在自己的服务空间完成验证再购买。

2026-10-01,阿里云开发者版空间、Node 16.15.1、Chrome 中的官方 uniCloud 客户端 SDK 实测通过:三图与工作簿内嵌原资源逐字节一致,未匹配和空命名计数均为 0;未知字段和无效工作簿返回结构化错误。未实测腾讯云、支付宝云、其他客户端环境或接近上限的大文件。

限制与错误

  • 原始 .xlsx 文件最多 1 MiB;导出内容合计和最终 ZIP 各最多 1 MiB。
  • 解压后内容最多 12 MiB;单个 XML 最多 2 MiB;ZIP 条目最多 2000;DISPIMG 引用最多 200。
  • 最终返回 JSON 的 UTF-8 大小最多 1.5 MiB。这些是插件保守限制,不代表云平台最大传输能力。
  • 列名范围 A–XFD,两列必须不同。所有工作表使用同一对列。
  • 仅接受 xlsxBase64、imageColumn、nameColumn 和可选的 SDK uniIdToken 元数据,不接受 URL。元数据不用于身份认证。
  • 错误包括 INVALID_INPUT、INPUT_LIMIT、OUTPUT_LIMIT、ZIP_INVALID 和 CALL_SOURCE_REJECTED,以实际返回的 error.code 为准。

数据处理与费用

文件发送到买家自己选择的 uniCloud 空间,在函数内存中处理;作者不接收文件。本函数不主动联网、落盘、写日志、数据库或云存储。云平台和接入页面的日志策略由相应运营者管理。

函数只检查平台提供的客户端调用来源,不提供用户身份、支付、业务权限或防滥用系统。接入方负责文件处理权限、调用安全、平台授权配置和云空间费用;插件购买费用不包含云资源费用。

依赖精确锁定为 @xmldom/xmldom 0.9.12 和 fflate 0.8.3,完整 MIT 许可证见 THIRD_PARTY_NOTICES.txt。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无。仅为云函数,不自行申请客户端系统权限。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

工作簿Base64发送至买家选择的uniCloud服务空间,仅在函数内存中处理;作者不接收或存储文件。不主动写日志、数据库或云存储;平台和买家自身日志策略由其管理。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无。

暂无用户评论。