HOME ABOUT
I AM HERE
Bookmark and Share

Downloading and uploading documents to SharePoint with metadata

January 8, 2008 10:42 by aidan

I need to copy some documents from a SharePoint 2003 server to a MOSS 2007 server to make them available on our Internet sites. This is quite easily achieved using the object model but what I also need is to move the metadata associated with the document so I can filter correctly on the Internet site.

To do this I have started by creating a couple of methods. One to download the document from SharePoint to a file system folder and create an xml document that contains the metadata in the same folder. The second method uploads the document with it the metadata to a destination SharePoint document library.

private void DownloadDocumentFromLibrary()
  {
   try
   {
    //get site
    SPSite oSite = new SPSite("http://Localhost");
    
    using(oSite)
    {
     //get the rootSite
     SPWeb oWeb = oSite.RootWeb;
    
     SPList oList = oWeb.Lists["Shared Documents"];

     foreach(SPListItem oItem in oList.Items)
     {
      //get meta-data for the item
      string strXML = oItem.Xml.ToString();
      TextWriter tw = new StreamWriter("c:\\MyDownloadFolder\\"+oItem["Name"]+".xml");
      //write xml to file
      tw.WriteLine(strXML);
      tw.Close();

      //get document
      byte[] binFile = oItem.File.OpenBinary();
      System.IO.FileStream fstream = System.IO.File.Create("c:\\MyDownloadFolder\\" + oItem["Name"]); 
      
      //write document to folder
      fstream.Write(binFile, 0, binFile.Length);
     } 
    }
   }
   catch(Exception err)
   {
    Console.WriteLine(err.Message);
   }
  }

The second method then takes the downloaded files and uploads them to the Internet server document library. You may need to find a way to physically move the files across the network using FTP or something similar depending on where your Internet server is and what security surrounds it.

private void UploadDocumentFromFileShare()
  {  
   try
   {
    //get site
    SPSite oSite = new SPSite("
http://Localhost");

    // Process the list of files found in the directory.
    string [] fileEntries = Directory.GetFiles(@"c:\mydownloadfolder");
    foreach(string fileName in fileEntries)
    {
     //check file type to see if it is an xml document
     int iFileNameLength = fileName.Length;
     string strFileExtension = fileName.Substring(iFileNameLength-4,4);
    
     if(strFileExtension != ".xml")
     {
      //Load the local file into a stream
      FileStream stream = File.OpenRead(fileName);
      byte[] content = new byte[stream.Length];
 
      //Read the file into a byte array
      stream.Read(content,0,(int)stream.Length);
      stream.Close();

      using(oSite)
      {
       //Get the rootSite
       SPWeb oWeb = oSite.RootWeb;
       //Get the folder that should store the document
       SPFolder folder = oWeb.Folders["upload"];

       string[] strSplitFileName = fileName.Split('\\');
       string strFileName = strSplitFileName[strSplitFileName.Length-1];
       //add document to library
       folder.Files.Add(folder.Url + "/" + strFileName, content,true);
 
       //get list
       SPList oList = oWeb.Lists["upload"];
       //create query to get added document item
       SPQuery oQuery = new SPQuery();
       oQuery.Query = "<Where><Eq><FieldRef Name='FileLeafRef' /><Value Type='File'>"+strFileName+"</Value></Eq></Where>";
   
       SPListItemCollection oItems = oList.GetItems(oQuery);

       //get xml for document properties
       XmlTextReader reader = new XmlTextReader(fileName+".xml");
    
       XmlDocument doc = new XmlDocument();
       doc.Load(reader);
       XmlElement root = doc.DocumentElement;
       XmlNode node = root.Attributes.GetNamedItem("ows_Column1");
       string strColumn1= node.Value.ToString();

       foreach(SPListItem oItem in oItems)
       {
        string strTitle = "";
        strTitle = strFileName.Substring(0,strFileName.Length-4);
        oItem["Title"] = strTitle;
        oItem["Column1"] = strColumn1;

        oItem.Update();
       }
      }
     } 
    }
   }
   catch(Exception err)
   {
    Console.WriteLine(err.Message);
   }
  }

It is also possible to download attachments from an item using the following code:

 private void DownloadAttachmentFromItem()
  {
   //download attachment from a list to file system
   SPWeb web = new SPSite("
http://localhost").OpenWeb();
   
   //Open List
   SPList list = web.Lists["Doc List"];
      
   foreach(SPListItem oItem in list.Items)
   {
    //get meta-data for the item
    string strXML = oItem.Xml.ToString();
    TextWriter tw = new StreamWriter("c:\\MyDownloadFolder\\"+oItem["Title"]+".xml");
    tw.WriteLine(strXML);
    tw.Close();

    //Get the folder
    SPFolder folder = web.Folders["Lists"].SubFolders["Doc List"].SubFolders["Attachments"].SubFolders[oItem.ID.ToString()];
    //download attachment
    foreach(SPFile oFile in folder.Files)
    {
     byte[] binaryFile = oFile.OpenBinary();
     System.IO.FileStream fstream = System.IO.File.Create("c:\\MyDownloadFolder\\" + oItem["Title"]); 
     fstream.Write(binaryFile, 0, binaryFile.Length);
    }
   }
  }


Tags:
Categories: MOSS 2007
Actions: E-mail | Permalink | Comments (11) | Comment RSSRSS comment feed

Comments

January 14. 2008 16:29

Hi

Do you know if it is possible to apply the same principles and retrieve approval information as well. I need to restore a document library but make sure it keeps the metadata as well as approval information. I have tried a few options such as save as a template, custom app and dragging files using the explorer view but i can't get any of these to work. The only way i know it should work is by restoring the whole site from a backup but i can;t do that. Any suggestions?

Raymond

March 25. 2008 20:22

Good article. You can use GetFiles with a search pattern to find only XML files. Otherwise, the extension comparison operator should be == and not !=.

Dave

March 25. 2008 20:25

Oh, another thing with files...compare with all lowercase, such as
if (strFileExtension.ToLower().EndsWith(".xml") ) { ... }

Dave

January 14. 2009 20:15

How does the download method handle folders in the document library?

BIT99

February 27. 2009 15:26

Heres 4 lines of code to upload a whole directory of files, in this case pictures, to a SharePoint document or image library.
The directory pictures contains the images.
The destination is the image library SiteCollectionImages for the portal running on port 2828

$wc = new-object System.Net.WebClient
$wc.Credentials = [System.Net.CredentialCache]:LaughingefaultCredentials
function getdestname($filename){ "http://sps:2828/sitecollectionimages/" + $(split-path -leaf $filename)}
dir "pictures" | % { $uploadname=getdestname $_; $wc.UploadFile($uploadname,"PUT", $_.FullName) }

Have I mentioned PowerShell just rocks?

Ben McInerney

March 4. 2009 10:41

Can you please tell how can i search a document/folder using the metadata?

Sen

March 28. 2009 11:22

Dave - in that if statement I am checking that it is not an xml file as the non xml files are the ones to be uploaded so the code is correct. Cheers.

Aidan

March 28. 2009 11:23

Raymond - I have never tried to move approval information too. It is probably a bit tricky to move approval tasks too but you could use approval status on the item if that is sufficient?

Aidan

March 28. 2009 11:25

BIT99 - it doesn't handle folders in this example but you could code it to iterate through a folder structure if that was required.

Aidan

March 28. 2009 11:27

Ben - thanks for that powershell is something I need to take a look at. However, this post is for moving documents with meta-data not simply bulk uploading from the file system so it isn't really comparing apples with apples. Thanks for the comment though.

Aidan

March 28. 2009 11:30

Sen - based on your email sent directly the answer is that you can use CAML queries to search a document/folder using meta data.

Aidan

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading