Dump all the Lists in A SharePoint Web to Excel CSV Files
Please use the page tabs to navigate through the article.
Sometime ago I wrote an article about using C# console applications to access and perform tasks in SharePoint. One example I use often is a dump of all lists in a site to CSV.
Between native and 3rd party options there are probably 86 ways to backup SharePoint. However sometimes you want something simple and guarenteed. The Export to Spreadsheet option is an example – its basic but works – kind of cosey.
So I wrote a console app that lets me quickly dump the contents of a Site to a series of CSV files and zips them. It literally only takes seconds and is a good “just-in-case” prior to performing any changes.
You call the application by
BackupListsToCSV.exe "SiteName" "WebName"
or
BackupListsToCSV.exe "SiteName" "WebName/SubWebName"
for further down the tree.
The app starts with Main confirming the arguments and if ok running the BackupWebToCSV method;
static void Main(string[] args)
{
try
{
//confirm arguments
if (!String.IsNullOrEmpty(args[0].ToString())
&& !String.IsNullOrEmpty(args[1].ToString()))
BackupWebToCSV(args[0].ToString(), args[1].ToString());
}
catch
{
//else generate error
Console.WriteLine("ERROR: SITE or WEB not specified.");
Console.WriteLine("try: BackupSite.exe \"http://yoursitename/\""
+ " \"yourwebname\"");
}
}
The BackupWebToCSV goes through each list in the Web and backs it up to CSV (BackupWebToCSV) and once they are all done compresses the CSV files into a Zip;
private static void BackupWebToCSV(string site, string web)
{
try
{
//bind to site and web
using(SPSite oSite = new SPSite(String.Format("{0}/", site.Trim('/'))))
{
using(SPWeb oWeb = oSite.OpenWeb(web))
{
foreach(SPList oList in oWeb.Lists)
{
//backup each list
BackupListToCSV(oList);
}
}
}
//compress the files into a zip
CompressFiles();
}
catch (Exception Ex)
{
Console.WriteLine(String.Format("Error: {0}", Ex));
}
}
To backup the list to CSV I use the following method;
private static void BackupListToCSV(SPList oList)
{
Console.WriteLine(String.Format("Backing up {0}", oList.Title));
//get the list of headings for the list
List <string> Headings = Get_Headings(oList);
//create a content object
StringBuilder CSVFileContent = new StringBuilder();
//add the field names as the CSV headings
string line = String.Empty;
foreach(string Heading in Headings)
line += String.Format("\"{0}\",", Heading);
CSVFileContent.AppendLine(line.Trim(','));
//bind to the list items
SPListItemCollection oCollection = oList.Items;
foreach(SPListItem oItem in oCollection)
{
//for each item add the values to the content
line = String.Empty;
foreach(string Heading in Headings)
line += oItem[Heading] == null
? String.Format("\"{0}\",", String.Empty)
: String.Format("\"{0}\",", oItem[Heading].ToString());
CSVFileContent.AppendLine(line.Trim(','));
//display some progress on the screen
Console.Write(".");
}
//save the csv file
SaveCSVFile(oList.Title, CSVFileContent);
//null the collection
oCollection = null;
}
Its a bit long, but it is relatively simple. First it creates a list of all the field names in the SPList;
List <string> Headings = Get_Headings(oList);
...
...
private static List < string > Get_Headings(SPList oList)
{
List < string > Headings = new List < string > ();
foreach(SPField field in oList.Fields)
Headings.Add(field.InternalName);
return (Headings);
}
It then uses this list of field names as the column names of the CSV, ie its first line;
foreach(string Heading in Headings)
line += String.Format("\"{0}\",", Heading);
CSVFileContent.AppendLine(line.Trim(','));
Using this same list, I can then get the value for that field name for each item, build a CSV string, then add it to the content;
foreach(SPListItem oItem in oCollection)
{
//for each item add the values to the content
line = String.Empty;
foreach(string Heading in Headings)
line += oItem[Heading] == null
? String.Format("\"{0}\",", String.Empty)
: String.Format("\"{0}\",", oItem[Heading].ToString());
CSVFileContent.AppendLine(line.Trim(','));
//display some progress on the screen
Console.Write(".");
}
Notice to handle null records I set the value as String.Empty;
line += oItem[Heading] == null
? String.Format("\"{0}\",", String.Empty)
: String.Format("\"{0}\",", oItem[Heading].ToString());
Once all the items have been added to the content, I can write it to disk;
SaveCSVFile(oList.Title, CSVFileContent);
...
...
private static void SaveCSVFile(String Title, StringBuilder Content)
{
string FileName = String.Format("{0}.csv", Title);
FileNames.Add(FileName);
TextWriter writer = new StreamWriter(FileName);
writer.Write(Content.ToString());
writer.Close();
writer.Dispose();
}
This process goes through all the lists pretty quickly, but depending on the Web you can end up with some pretty big CSV files, which are great candidates for compression.
I had a look around and settled on the ICSharpCode.SharpZipLib.dll library as it is fairly simple, is fast, and has worked in every scenario Ive needed.
private static void CompressFiles()
{
Console.WriteLine(String.Format("Compressing {0} files", FileNames.Count));
//create the zip file name
string ZipFileName = String.Format("{0}-{1}-{2}.zip",
DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
//set up the zip file
ZipOutputStream ZipFile = new ZipOutputStream(File.Create(ZipFileName));
ZipFile.SetLevel(9); //highest compression
byte[] buffer = new byte[4096];
//for each csv file
foreach(string FileName in FileNames)
{
ZipEntry ZipFileEntry = new ZipEntry(FileName);
ZipFileEntry.DateTime = DateTime.Now;
ZipFile.PutNextEntry(ZipFileEntry);
//stream the file into the zip
using(FileStream fs = File.OpenRead(FileName))
{
int SourceBytes;
do
{
SourceBytes = fs.Read(buffer, 0, buffer.Length);
ZipFile.Write(buffer, 0, SourceBytes);
Console.Write(".");
} while (SourceBytes > 0);
}
}
//finalise the zip
ZipFile.Finish();
ZipFile.Close();
//delete the source files
DeleteFiles();
}
The entire application is only 180 lines long, and in my main example extracts some 500,000 records from about 30 lists and compresses them down to a 19Mb file in about a minute – not bad.
Click here and go to see the full code on the next tab else you can download the solution below!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
namespace BackupListsToCSV
{
class Program
{
public static List < string > FileNames = new List < string > ();
static void Main(string[] args)
{
try
{
//confirm arguments
if (!String.IsNullOrEmpty(args[0].ToString())
&& !String.IsNullOrEmpty(args[1].ToString()))
BackupWebToCSV(args[0].ToString(), args[1].ToString());
}
catch
{
//else generate error
Console.WriteLine("ERROR: SITE or WEB not specified.");
Console.WriteLine("try: [].exe \"http://yoururl.com/\""
+ "\"TheGateway\"");
}
}
private static void BackupWebToCSV(string site, string web)
{
try
{
//bind to site and web
using(SPSite oSite = new SPSite(String.Format("{0}/", site.Trim('/'))))
{
using(SPWeb oWeb = oSite.OpenWeb(web))
{
foreach(SPList oList in oWeb.Lists)
{
//backup each list
BackupListToCSV(oList);
}
}
}
//compress the files into a zip
CompressFiles();
}
catch (Exception Ex)
{
Console.WriteLine(String.Format("Error: {0}", Ex));
}
}
private static void BackupListToCSV(SPList oList)
{
Console.WriteLine(String.Format("Backing up {0}", oList.Title));
//get the list of headings for the list
List < string > Headings = Get_Headings(oList);
//create a content object
StringBuilder CSVFileContent = new StringBuilder();
//add the field names as the CSV headings
string line = String.Empty;
foreach(string Heading in Headings)
line += String.Format("\"{0}\",", Heading);
CSVFileContent.AppendLine(line.Trim(','));
//bind to the list items
SPListItemCollection oCollection = oList.Items;
foreach(SPListItem oItem in oCollection)
{
//for each item add the values to the content
line = String.Empty;
foreach(string Heading in Headings)
line += oItem[Heading] == null
? String.Format("\"{0}\",", String.Empty)
: String.Format("\"{0}\",", oItem[Heading].ToString());
CSVFileContent.AppendLine(line.Trim(','));
//display some progress on the screen
Console.Write(".");
}
//save the csv file
SaveCSVFile(oList.Title, CSVFileContent);
//null the collection
oCollection = null;
}
private static List < string > Get_Headings(SPList oList)
{
List < string > Headings = new List < string > ();
foreach(SPField field in oList.Fields)
Headings.Add(field.InternalName);
return (Headings);
}
private static void SaveCSVFile(String Title, StringBuilder Content)
{
string FileName = String.Format("{0}.csv", Title);
FileNames.Add(FileName);
TextWriter writer = new StreamWriter(FileName);
writer.Write(Content.ToString());
writer.Close();
writer.Dispose();
}
private static void CompressFiles()
{
Console.WriteLine(String.Format("Compressing {0} files", FileNames.Count));
//create the zip file name
string ZipFileName = String.Format("{0}-{1}-{2}.zip",
DateTime.Now.Year,
DateTime.Now.Month,
DateTime.Now.Day);
//set up the zip file
ZipOutputStream ZipFile = new ZipOutputStream(File.Create(ZipFileName));
ZipFile.SetLevel(9); //highest compression
byte[] buffer = new byte[4096];
//for each csv file
foreach(string FileName in FileNames)
{
ZipEntry ZipFileEntry = new ZipEntry(FileName);
ZipFileEntry.DateTime = DateTime.Now;
ZipFile.PutNextEntry(ZipFileEntry);
//stream the file into the zip
using(FileStream fs = File.OpenRead(FileName))
{
int SourceBytes;
do
{
SourceBytes = fs.Read(buffer, 0, buffer.Length);
ZipFile.Write(buffer, 0, SourceBytes);
Console.Write(".");
} while (SourceBytes > 0);
}
}
//finalise the zip
ZipFile.Finish();
ZipFile.Close();
//delete the source files
DeleteFiles();
}
private static void DeleteFiles()
{
foreach(string FileName in FileNames)
File.Delete(FileName);
}
}
}



Recent Comments