Tuesday, June 12, 2007

SharePoint List Importer/Exporter: Part II

Once I had the settings from the XML file, I placed all the settings into a dictionary object for easy access. Next I had some code that checks to see if we are creating a new list or just adding to a current one. This uses the typical site/web setup.

I check the listname against the site to see if the list already exists. If the list exists, I check to see if I am creating folders and set the EnableFolderCreation property if I am.

If the list does not exist, I create it and set some properties.

SPList list = null;
if(web.Lists[inputs.ListName] != null){
list = web.Lists[inputs.ListName];
list.EnableFolderCreation = (inputs.GetItemType == ItemType.Folders inputs.GetItemType == ItemType.FoldersAndItems ? true : false);
}
else
{
Guid guid = web.Lists.Add(inputs.ListName, inputs.ListTitle.Replace("_", " "), SPListTemplateType.CustomGrid);
list = web.Lists[guid];
list.EnableVersioning = true;
list.OnQuickLaunch = true;
list.ReadSecurity = 1;
list.WriteSecurity = 2;
list.EnableFolderCreation = (inputs.GetItemType == ItemType.Folders inputs.GetItemType == ItemType.FoldersAndItems ? true : false);
}
web.AllowUnsafeUpdates = true;
list.Update();

Now I have the list object that I am going to be writing my folders and items to. I next call my import routine.

Part of this import routine if reading from the CSV files. You could alternatively use another SharePoint list or multiple lists as your import source. For the purpose of this demo I will not display the code to parse out a CSV file because are alot of sites out there that will show you haw to do that. For the import, we need to set our fields for the list. So to start the import, I read the 3 header lines from the file and then call a routine to create the fields in the list.

I placed the header data into 3 generic lists and interate through them. First I check to see if the list already contains a definition for the current field; if it does not, I add the field to the list definition by defining name, type and required.

for (int y = 0; y <= flds.Count - 1; y++) { string fld = flds[y].Replace(" ", ""); if (!list.Fields.ContainsField(flds)) { try { list.Fields.Add(fld, typs[y], reqs[y]); } catch { continue; } } } web.AllowUnsafeUpdates = true; list.Update();


I run the same process using the item field information. This ensures that all the fields are in the list.
Now the list is ready to receive the data, so the next step is to place all the data for the items into a container for quick reference. I placed the entire file into DataTable.

Next I stream in the folder CSV file. I read each line into an array called values. Then we compute the url for the list items using...
string url = string.Format("{0}/{1}", list.ParentWeb.Url, list.RootFolder.Url);

The xml settings included a node for formatting the name/title, i do this on the first line, creating essentially a computed field.
string name = String.Format("{0}-{1} {2}", values[0], values[1], values[2]).Trim();


Now we can loop through the folders definitions in the stream. Make sure you set the second value in the Add Method to SPFileSystemObjectType.Folder or else you will create items. I had placed all the field names into a list previously called fflds, so now I loop through the list and set the value for each field in the form. Finally I set the title field and save the new list folder.

while (values = csv.GetLine())
SPListItem item = list.Items.Add(url, SPFileSystemObjectType.Folder, name);
for (int i = 0; i <>

item.Update();

After the list folder has been created, now I go to the items datatable and filter it on the key field in the list folder, matching against the items. Then I loop through each item DataRow in the filtered view and add the item and set its field values. Notice that when I create the item, I set the item url to the folder url. I then save each item and loop back to get the next folder.

dt.DefaultView.RowFilter = GetFilter(item, fflds, keyStr, keys);
for (int o = 0; o < item_url =" string.Format(" folderitem =" list_items.Add(item_url," i =" 0;">

The whole process runs in under 1 minute for 3000 folders with mixed items. Even though I know there are some $$$ tools out there that can do this. For those of you without the budget this is a good place to start on your own list importer. If you would like me to send you the source for this part of the application, just send me an email. :)

In the next version I will tackle exporting complex lists into a format that is digestable by other applications.

JMC


2 comments:

dave said...

where is this code written? Are u using the Code listed in an external web app or windows app?

dave said...

I am new to sharepoint. I see the pages in SharePoint Designer. Are u saying that the code u mentioned written there or is its used in a win or web app.