You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JavaScript复制SharePoint宏启用Excel文件后文件损坏问题排查

问题

我的SharePoint文档库中存储着带宏的Excel文件(.xlsm),想用JavaScript复制并重命名生成副本供用户编辑。当前代码能完成复制重命名操作,但打开生成的文件时会弹出错误提示:

We found a problem with some content with filename.xlsm. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes

点击"Yes"后提示关闭,但无法恢复内容,手动修改扩展名也无法解决问题,推测是代码逻辑导致文件损坏,需要排查问题或寻找替代实现方案。

当前使用的代码:

function copyAndRenameTemplate(fileName, templateFilePath, destinationFolderPath) {
        getFormDigestValue().then(function(formDigestValue) {
            // Get template file's unique id
            $.ajax({
                url: "https://mysiteurl/sites/subsite/_api/web/getfilebyserverrelativeurl('" + templateFilePath + "')",
                type: "GET",
                headers: {
                    "Accept": "application/json;odata=verbose",
                    "X-RequestDigest": formDigestValue
                },
                success: function(data) {
                    var templateFileUniqueId = data.d.UniqueId;

                    // Copy template file to destination folder
                    $.ajax({
                        url: "https://mysiteurl.ca/sites/subsite/_api/web/getfolderbyserverrelativeurl('" + destinationFolderPath + "')/Files/add(url='" + fileName + ".xlsm', overwrite=true)",
                        type: "POST",
                        headers: {
                            "Accept": "application/json;odata=verbose",
                            "X-RequestDigest": formDigestValue,
                            "X-HTTP-Method": "POST",
                            "If-Match": "*",
                            "Content-Type": "application/json;odata=verbose"
                        },
                        data: JSON.stringify({
                            'type': 'SP.File',
                            'sourceUniqueId': templateFileUniqueId
                        }),
                        success: function(data) {
                            console.log("File copied and renamed successfully.");
                        },
                        error: function(error) {
                            console.log("Error copying and renaming file: " + JSON.stringify(error));
                        }
                    });
                },
                error: function(error) {
                    console.log("Error retrieving template file: " + JSON.stringify(error));
                }
            });
        }).catch(function(error) {
            console.error('Error retrieving form digest: ', error);
            alert('Failed to retrieve form digest value: ' + JSON.stringify(error));
        });
    }
解决方案

问题根源

你当前使用的Files/add方法搭配sourceUniqueId参数的方式,并非SharePoint官方推荐的文件复制逻辑。这种方式本质是尝试创建新文件并关联源文件ID,但并未正确读取源文件的二进制内容,导致生成的文件仅包含元数据,实际内容为空或格式损坏——对于.xlsm这类二进制复合文件(包含宏容器),这种错误会直接导致文件无法正常打开。

方案1:使用SP.File.copyTo方法(推荐)

SharePoint REST API提供了专门的copyTo方法用于文件复制,能完整保留文件的所有内容和属性,包括宏数据,不会损坏文件。

修改后的代码:

function copyAndRenameTemplate(fileName, templateFilePath, destinationFolderPath) {
    getFormDigestValue().then(function(formDigestValue) {
        // 拼接目标文件的完整服务器相对路径
        const destinationFileUrl = `${destinationFolderPath}/${fileName}.xlsm`;
        
        // 调用源文件的copyTo方法完成复制
        $.ajax({
            url: `https://mysiteurl/sites/subsite/_api/web/getfilebyserverrelativeurl('${templateFilePath}')/copyTo(strNewUrl='${destinationFileUrl}', boverwrite=true)`,
            type: "POST",
            headers: {
                "Accept": "application/json;odata=verbose",
                "X-RequestDigest": formDigestValue
            },
            success: function() {
                console.log("文件复制并重命名成功");
            },
            error: function(error) {
                console.log("复制文件出错: " + JSON.stringify(error));
            }
        });
    }).catch(function(error) {
        console.error('获取Form Digest失败: ', error);
        alert('获取Form Digest失败: ' + JSON.stringify(error));
    });
}

关键说明

  • copyTo是SharePoint原生的文件复制API,会完整复制文件的二进制内容、宏、权限等所有属性。
  • 无需提前获取源文件的UniqueId,直接通过源文件的服务器相对路径调用方法即可。
  • 参数boverwrite=true保持原逻辑,允许覆盖目标路径的同名文件。

方案2:读取源文件二进制内容后上传

如果因权限或环境限制无法使用copyTo,可以先读取源文件的二进制Blob数据,再上传到目标路径,确保文件内容完整。

代码示例:

function copyAndRenameTemplate(fileName, templateFilePath, destinationFolderPath) {
    getFormDigestValue().then(function(formDigestValue) {
        // 第一步:读取源文件的二进制Blob内容
        $.ajax({
            url: `https://mysiteurl/sites/subsite/_api/web/getfilebyserverrelativeurl('${templateFilePath}')/$value`,
            type: "GET",
            headers: {
                "X-RequestDigest": formDigestValue
            },
            responseType: "blob",
            success: function(blobData) {
                // 第二步:通过FormData上传Blob到目标文件夹
                const formData = new FormData();
                formData.append("file", blobData, `${fileName}.xlsm`);
                
                $.ajax({
                    url: `https://mysiteurl/sites/subsite/_api/web/getfolderbyserverrelativeurl('${destinationFolderPath}')/Files/add(overwrite=true)`,
                    type: "POST",
                    headers: {
                        "X-RequestDigest": formDigestValue
                    },
                    processData: false,
                    contentType: false,
                    data: formData,
                    success: function() {
                        console.log("文件复制并重命名成功");
                    },
                    error: function(error) {
                        console.log("上传文件出错: " + JSON.stringify(error));
                    }
                });
            },
            error: function(error) {
                console.log("读取源文件出错: " + JSON.stringify(error));
            }
        });
    }).catch(function(error) {
        console.error('获取Form Digest失败: ', error);
        alert('获取Form Digest失败: ' + JSON.stringify(error));
    });
}

关键说明

  • 通过$value端点获取文件的原始二进制Blob数据,确保完整读取.xlsm的所有内容(包括宏容器)。
  • 使用FormData上传Blob,避免JSON序列化导致的二进制数据损坏。
  • 这种方式适合需要对文件内容做修改后再上传的场景,同样能保证文件完整性。

内容的提问来源于stack exchange,提问作者Toner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:37:03