在sharepoint中将列表项从一个列表复制到另一个列表

时间:2009-07-02 16:19:35

标签: c# sharepoint

在Sharepoint中,如何将列表项从一个列表复制到另一个列表 例如,从“列表A”复制到“列表B”(两者都在站点的根目录)

我希望在将新列表项添加到“列表A”

时进行此复制

我尝试在ItemAdded事件接收器中使用SPListItem的CopyTo()方法,但无法找出要复制到的URL。

11 个答案:

答案 0 :(得分:17)

这是我使用的代码。传递一个SPlistItem和目标列表的名称,如Sharepoint(不是URL)中所示。唯一的限制是两个列表必须位于同一站点:

private SPListItem CopyItem(SPListItem sourceItem, string destinationListName) {
        //Copy sourceItem to destinationList
        SPList destinationList = sourceItem.Web.Lists[destinationListName];
        SPListItem targetItem = destinationList.Items.Add();
        foreach (SPField f in sourceItem.Fields) {
            //Copy all except attachments.
            if (!f.ReadOnlyField && f.InternalName != "Attachments"
                && null != sourceItem[f.InternalName])
            {
                targetItem[f.InternalName] = sourceItem[f.InternalName];
            }
        }
        //Copy attachments
        foreach (string fileName in sourceItem.Attachments) {
            SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
            byte[] imageData = file.OpenBinary();
            targetItem.Attachments.Add(fileName, imageData);
        }

        return targetItem;
    }

答案 1 :(得分:5)

事实上,正如Lars所说,移动项目并保留版本和更正用户信息可能很棘手。我之前做过类似的事情,所以如果你需要一些代码示例,请通过评论告诉我,并为你提供一些指导。

CopyTo方法(如果您决定使用它)需要一个绝对的Uri: http://host/site/web/list/filename.doc

因此,如果您在事件接收器中执行此操作,则需要合并包含所需元素的字符串。类似的东西(请注意,这可以通过其他方式完成):

string dest= 
 siteCollection.Url + "/" + site.Name + list.Name + item.File.Name;

答案 2 :(得分:1)

如果要保留所有元数据,时间戳,作者信息和版本历史记录,在SharePoint中复制和移动文件,项目和文件夹可能会非常棘手。看看CopyMove for SharePoint - 它还有一个Web服务API。

答案 3 :(得分:1)

市场上有很多工具可以将列表项复制到另一个列表(avepoint,metavis等),但是如果你打算只在一个列表上执行此操作,那么这些工具非常昂贵。

如果您可以每周手动执行一次,例如,请查看以下工具:http://en.share-gate.com/sharepoint-tools/copy-move-sharepoint-list-items-with-metadata-and-version-history

答案 4 :(得分:1)

确保在SPFile上调用CopyTo(url)方法,而不是在SPListItem上调用。 例如:

ItemUpdated(SPItemEventProperties properties)
{ 
  //...
  string url = properties.Web.Site.Url + "/" + properties.Web.Name + "Lists/ListName/" + properties.ListItem.File.Name;
  //properties.ListItem.File.MoveTo(url);
  properties.ListItem.File.CopyTo(url);
  //...
}

答案 5 :(得分:1)

private void CopyAttachmentsToList(SPListItem srcItem, SPListItem tgtItem)
{
    try
    {
        //get source item attachments from the folder
        SPFolder srcAttachmentsFolder =
            srcItem.Web.Folders["Lists"].SubFolders[srcItem.ParentList.Title].SubFolders["Attachments"].SubFolders[srcItem.ID.ToString()];

        //Add items to the target item
        foreach (SPFile file in srcAttachmentsFolder.Files)
        {
            byte[] binFile = file.OpenBinary();
            tgtItem.Update();
            tgtItem.Attachments.AddNow(file.Name, binFile);
            tgtItem.Update();
        }
    }
    catch
    {
        //exception message goes here
    }
    finally
    {
        srcItem.Web.Dispose();
    }
}

不要忘记添加此行tgtItem.Update();,否则您将收到错误。

答案 6 :(得分:0)

那么,列表是否具有完全相同或相似的列?无论哪种方式,您都可以创建一个在“列表A”中创建项目时自动运行的简单工作流程。由于相关工作流程相对简单,我建议使用SharePoint Designer(免费)来创建它,因为您可以轻松匹配两个列表中的列。下面的步骤应该可以帮助你开始。

Create a Workflow - SharePoint Designer

答案 7 :(得分:0)

我遇到了同样的问题。

尝试了一点而不是

targetItem[f.InternalName] = sourceItem[f.InternalName];

我用过:

targetItem[childField.Title] = sourceItem[parentField.Title];

答案 8 :(得分:0)

这是一个类似于Sylvian的powershell,允许跨站点复制。他的代码也可以同样修改......

param([string]$sourceWebUrl, [string]$sourceListName, [string]$destWebUrl, [string]$destListName)

$sourceWeb = get-spweb $sourceWebUrl;
$sourceList = $sourceWeb.Lists[$sourceListName];
$destWeb = get-spweb $destWebUrl;
$destList = $destWeb.Lists[$destListName];
$sourceList.Items |%{
$destItem = $destList.Items.Add();
$sourceItem = $_;
$sourceItem.Fields |%{
    $f = $_;
    if($f.ReadOnlyField -eq $false -and $f.InternalName -ne "Attachments" -and $sourceItem[$f.InternalName] -ne $null){
        $destItem[$f.InternalName] = $sourceItem[$f.InternalName];
    }
}
$destItem.Update();
}

使用,复制和过去文件copy-listitems.ps1并使用Sharpoint powerhsell命令行运行...

答案 9 :(得分:0)

如何复制字段和保存版本:

public static SPListItem CopyItem(SPListItem sourceItem, SPList destinationList)
            {
                SPListItem targetItem = destinationList.AddItem();

                //loop over the soureitem, restore it
                for (int i = sourceItem.Versions.Count - 1; i >= 0; i--)
                {
                    //set the values into the archive 
                    foreach (SPField sourceField in sourceItem.Fields)
                    {
                        SPListItemVersion version = sourceItem.Versions[i];

                        if ((!sourceField.ReadOnlyField) && (sourceField.InternalName != "Attachments"))
                        {
                            SetFields(targetItem, sourceField, version);
                        }
                    }

                    //update the archive item and 
                    //loop over the the next version
                    targetItem.Update();
                }

                foreach (string fileName in sourceItem.Attachments)
                {
                    SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
                    targetItem.Attachments.Add(fileName, file.OpenBinary());
                }

                targetItem.SystemUpdate();
                return targetItem;
            }

            private static bool SetFields(SPListItem targetItem, SPField sourceField, SPListItemVersion version)
            {
                try
                {
                    targetItem[sourceField.InternalName] = version.ListItem[sourceField.InternalName];
                    return true;
                }
                catch (System.ArgumentException)//field not filled
                {
                    return false;
                }
                catch (SPException)//field not filled
                {
                    return false;
                }
            }

答案 10 :(得分:0)

使用c#服务器端代码将列表项从一个SharePoint列表或库复制到另一个SharePoint列表或库

// Itecollection是源列表

中的数据集合
 public void CopyItemsFromOneListToAnotherList(SPListItemCollection itemCollection)
 {  
 using (SPSite site = new SPSite(siteUrl))
 {
  using (SPWeb web = site.OpenWeb())
  {
     //Get destination list/library
     //destListName - Destination list/library name
   SPList destList = web.Lists.TryGetList(destListName);

   foreach (SPListItem sourceItem in itemCollection)
   {
    //Add new Item to list
    SPListItem destItem = destList.Items.Add();

    foreach (SPField field in sourceItem.Fields)
    {
     if (!field.ReadOnlyField && !field.Hidden && field.InternalName != "Attachments")
     {
      if (destItem.Fields.ContainsField(field.InternalName))
      {
       //Copy item to  destination library
         destItem[field.InternalName] = sourceItem[field.InternalName];
      }
     }
    }
    //Update item in destination  library or list
    destItem.Update();
    Console.WriteLine("Copied " + sourceItem["ID"] + "to destination list/library");
   }
  }
 }

 }