使用 javascript 在 SharePoint 中的文档库之间根据自定义列值复制文件

Copying Files based on a custom column value between document libraries in SharePoint using javascript

我是 Javascript 的新手,目前正在执行一项任务,我需要根据 自定义列名 "PID" 从 One Document 复制文件图书馆给对方。

我能够使用下面的代码来复制所有文件

$scope.copyFiles=function()
{

var sourceLib = '/sites/Protocol/ProtocolDocument';
var destLib = '/sites/Protocol/FinalProtocolDocuments';


var context = new SP.ClientContext.get_current();
var web = context.get_web().get_lists();
var folderSrc = web.getFolderByServerRelativeUrl(sourceLib);
//var cq = "<Query><Where><Eq><FieldRef Name="ProtocolID" LookupId="TRUE"/><Value Type="Text">' + 466 + '</Value></Eq></Where></Query>"
context.load(folderSrc,'Files');
context.executeQueryAsync(
function() {

           console.log("Got the source folder right here!");
           var files = folderSrc.get_files();
           var e = files.getEnumerator();
           var dest = [];
           while (e.moveNext()) {
           var file = e.get_current();
           var destLibUrl = destLib + "/" + file.get_name();
           dest.push(destLibUrl); //delete this when we're happy we got the file paths right
           file.copyTo(destLibUrl, true);

           }

        console.log(dest); //delete this when we're happy we got the file paths right
        context.executeQueryAsync(function() { console.log("Files moved successfully!");}, function(sender, args) {console.log("error: ") + args.get_message()});
        }, 
    function(sender, args){console.log("Sorry, something messed up: " + args.get_message());}
    );   

   }

我在网上做了一些研究,希望根据自定义列值获取文件名,但没有成功

也尝试过使用 CAML,但不确定如何在代码中使用它。

如果有人可以帮助我根据自定义列名 "PID" 从文档库中获取文件名,以便只有 selected/filtered 个文件被移动到目标库,我将不胜感激。

更新代码

$scope.copyFiles=function()
{
   var sourceLib = '/sites/Protocol/ProtocolDocument';
   var destLib = '/sites/Protocol/FinalProtocolDocuments';
   PID='466'
   var context = new SP.ClientContext();
   var list = context.get_web().get_lists().getByTitle("ProtocolDocument");
   var cq = new SP.CamlQuery();
   cq.set_viewXml("<View><Query>" +
                  "<Where>" +
                  "<Eq><FieldRef Name=\"ProtocolID\"/><Value Type=\"Text\">PID</Value></Eq>" +
                  "</Where>" +
                  "</Query>" +
                  "</View>");

   var items = list.getItems(cq);
   context.load(items);
   context.executeQueryAsync(
   function() {
                 var e = items.getEnumerator();
                 var dest = [];
                 while (e.moveNext()) 
                 {
                   var file = e.get_current();
                   var destLibUrl = destLib + "/" + file.get_name();
                   dest.push(destLibUrl); //delete this when we're happy we got the file paths right
                   file.copyTo(destLibUrl, true);

                 }

        console.log(dest); //delete this when we're happy we got the file paths right
        context.executeQueryAsync(function() { console.log("Files moved successfully!");}, function(sender, args) {console.log("error: ") + args.get_message()});
        }, 
    function(sender, args){console.log("Sorry, something messed up: " + args.get_message());}
    );   

 }          

});

这是我的尝试。我在 SharePoint 2013 上成功测试了它,它将文件从一个文档库复制到另一个文档库,但只复制查找字段设置为特定值的文件。我包含了一个简短的摘要,但如果您只想要代码,请跳转到 现在到实际代码

请注意,我使用了 Internet Explorer 不支持的语法,如果您需要支持该浏览器,请告诉我。我还相信一个函数或方法应该只做一件事,所以我将功能拆分为三个独立的函数。这也有助于保持代码整洁和易于阅读。

总而言之:第一个函数 findAndCopyFiles() 将 运行 一次并查找具有您设置的查找字段值的所有文件。然后它将每个文件发送到 loadAndCopyFile() 函数以加载文件对象。此函数将为每个应复制的文件 运行 一次。当加载文件对象时,它被发送到第三个也是最后一个函数 copyFileTo(),该函数实际上会将文件复制到目标文档库。此函数还将 运行 每个文件一次。

现在进入实际代码

首先您需要根据您的设置设置这些配置变量:

const destinationLibraryPath = 'The path to your destination document library';
const sourceLibraryName = 'The name (not path) of your source document library';
const lookupField = 'The name of your lookup field';
const lookupValue = 'The value your lookup field should equal for files to be copied';

findAndCopyFiles()

该函数负责查找源文档库中查找字段设置为lookupValue值的所有文件。我们使用所谓的 CAML query 来过滤文件。您可以筛选所有可用的字段和列,而不仅仅是查找字段。

const findAndCopyFiles = () => {
    const clientContext = SP.ClientContext.get_current();
    const sourceList = clientContext.get_web().get_lists().getByTitle(sourceLibraryName);

    const camlQuery = new SP.CamlQuery();
    const whereQuery = `<Eq><FieldRef Name="${lookupField}"/><Value Type="Text">${lookupValue}</Value></Eq>`;
    camlQuery.set_viewXml(`<View><Query><Where>${whereQuery}</Where></Query></View>`);

    const sourceListItems = sourceList.getItems(camlQuery);

    clientContext.load(sourceListItems);
    clientContext.executeQueryAsync(
        () => {
            const filesEnumerator = sourceListItems.getEnumerator();
            while (filesEnumerator.moveNext()) {
                loadAndCopyFile(filesEnumerator.get_current(), clientContext);
            }
        },
        (_sender, args) => {
            console.log(args.get_message());
        }
    );
}

当查询执行时,我们使用 getEnumerator() 方法遍历查询返回的所有文件,换句话说,所有将被复制的文件。

loadAndCopyFile()

找到所有相关文件后,我们将每个文件发送到下一个函数以继续我们的过程。此函数将加载文件对象(如在实际文件中)并使用目标文档库的路径和文件的文件名构造目标 URL。

const loadAndCopyFile = (file, clientContext) => {
    const fileRef = file.get_file();

    clientContext.load(fileRef);
    clientContext.executeQueryAsync(
        () => {
            const destinationUrl = `${destinationLibraryPath}/${fileRef.get_name()}`;
            copyFileTo(fileRef, destinationUrl, clientContext);
        },
        (_sender, args) => {
            console.log(args.get_message());
        }
    );
}

copyFileTo()

最终函数负责将文件实际复制到目标文档库。它非常简单,看起来像这样:

const copyFileTo = (file, destinationUrl, clientContext) => {
    file.copyTo(destinationUrl, true);

    clientContext.executeQueryAsync(
        () => {
            console.log(`File copied to ${destinationUrl}!`);
        },
        (_sender, args) => {
            console.log(args.get_message());
        }
    );
}

综合起来

最后,当所有必需的库准备就绪时,我们执行 findAndCopyFiles() 函数:

SP.SOD.executeFunc('sp.js', 'SP.ClientContext', () => {
    findAndCopyFiles();
});

免责声明:我在另一台计算机上写了这个 post,而不是我测试代码的那台计算机,所以如果某些东西不起作用,可能是因为一个简单的语法错误。在这种情况下,请添加评论并告诉我!