using CSOM upload files and folders recursively & update metadata
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using SP = Microsoft.SharePoint.Client; using System.IO; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; namespace SPWidget { public partial class frmMain : Form { DataTable dt; HSSFWorkbook hssfworkbook; string _logPath = string.Format(GlobalConst.LOG_PATH, Application.StartupPath); public frmMain() { InitializeComponent(); } private void frmMain_Load(object sender, EventArgs e) { txtSiteUrl.Text = GlobalConst.SITE_URL; txtSiteDocPath.Text = GlobalConst.SITE_DOC_PATH; lblMessage.Text = string.Empty; if (!Directory.Exists(_logPath)) { Directory.CreateDirectory(_logPath); } } private void InitializeWorkbook(string path) { using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read)) { hssfworkbook = new HSSFWorkbook(file); } } private void ConvertToDataTable() { dt = new DataTable(); ISheet sheet = hssfworkbook.GetSheetAt(0); System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); for (int j = 0; j < 26; j++) { dt.Columns.Add(Convert.ToChar(((int)'A') + j).ToString()); } while (rows.MoveNext()) { IRow row = (HSSFRow)rows.Current; DataRow dr = dt.NewRow(); for (int i = 0; i < row.LastCellNum; i++) { ICell cell = row.GetCell(i); if (cell == null) { dr[i] = null; } else { dr[i] = cell.ToString(); } } dt.Rows.Add(dr); } } private void btnArchivePath_Click(object sender, EventArgs e) { var dlg = new FolderBrowserDialog(); if (dlg.ShowDialog() == DialogResult.OK) { txtArchivePath.Text = dlg.SelectedPath; } } private void btnExcelPath_Click(object sender, EventArgs e) { var dlg = new OpenFileDialog(); dlg.Filter = "Excel Files(*.xls,*.xlsx)|*.xls;*.xlsx"; if (dlg.ShowDialog() == DialogResult.OK) { txtExcelPath.Text = dlg.FileName; lblMessage.Text = "loading..."; Application.DoEvents(); InitializeWorkbook(dlg.FileName); ConvertToDataTable(); //A:FullPath,B:FileName,C:FolderStructure,D:Updater,E:UpdateDate,F:ProfileName,G:(Index_1,2,3,4,N...) dgvData.DataSource = dt; lblMessage.Text = string.Empty; } } /// <summary> /// add folder /// </summary> /// <param name="folderPath">etc:"aa/aa1/aa12"</param> private void AddFolder(string folderPath) { var ctx = new SP.ClientContext(txtSiteUrl.Text); ctx.Credentials = new System.Net.NetworkCredential(GlobalConst.USERNAME, GlobalConst.PASSWORD, GlobalConst.DOMAIN); var list = ctx.Web.Lists.GetByTitle("Documents"); if (folderPath.IndexOf("/") == -1) { list.RootFolder.Folders.Add(txtSiteDocPath.Text + "/" + folderPath); ctx.ExecuteQuery(); } else { var folderLevel = folderPath.Split('/'); for (int i = 0; i < folderLevel.Length; i++) { var folderCombine = string.Empty; for (int j = 0; j <= i; j++) { folderCombine += folderLevel[j] + "/"; } list.RootFolder.Folders.Add(txtSiteDocPath.Text + "/" + folderCombine.TrimEnd('/')); ctx.ExecuteQuery(); } } } /// <summary> /// add file /// </summary> /// <param name="filePath">full physical path</param> /// <param name="folderPath">etc:"aa/aa1/aa12/",必須要有"/"</param> /// <param name="fileName">file name</param> /// <param name="fields">meta column</param> /// <param name="values">meta data</param> /// <param name="values">log file name</param> private void AddFile(string filePath, string folderPath, string fileName, string[] fields, string[] values, string logFileName) { try { var ctx = new SP.ClientContext(txtSiteUrl.Text); ctx.Credentials = new System.Net.NetworkCredential(GlobalConst.USERNAME, GlobalConst.PASSWORD, GlobalConst.DOMAIN); var arrDocTitle = txtSiteDocPath.Text.Split('/'); var list = ctx.Web.Lists.GetByTitle(arrDocTitle[arrDocTitle.Length - 1].Replace("Shared Documents", "Documents")); if (!File.Exists(filePath)) { File.AppendAllText(_logPath + "/" + logFileName, string.Format("file \"{0}\" is not exists \r\n", filePath)); return; } var fileBytes = File.ReadAllBytes(filePath); var fileInfo = new SP.FileCreationInformation() { Url = txtSiteDocPath.Text + "/" + folderPath + fileName, Overwrite = true, Content = fileBytes }; var newfile = list.RootFolder.Files.Add(fileInfo); ctx.Load(newfile); //load target folder files var items = list.GetItems(new SP.CamlQuery() { FolderServerRelativeUrl = txtSiteDocPath.Text + "/" + folderPath }); ctx.Load(items); ctx.ExecuteQuery(); //update metadata var oItem = items.Single(x => x["FileLeafRef"].ToString() == fileName); for (var i = 0; i < fields.Length; i++) { oItem[fields[i]] = values[i]; } oItem.Update(); ctx.ExecuteQuery(); File.AppendAllText(_logPath + "/" + logFileName, string.Format("upload \"{0}\" success\r\n", filePath)); } catch (Exception ex) { File.AppendAllText(_logPath + "/" + logFileName, string.Format("upload \"{0}\" fail\r\n", filePath)); //MessageBox.Show(ex.Message); } } private void btnUpload_Click(object sender, EventArgs e) { lblMessage.Text = string.Empty; if (txtArchivePath.Text == "" || txtExcelPath.Text == "") { lblMessage.Text = "\"Archive Path\" and \"Excel Path\" can't be empty."; return; } var logFileName = GlobalConst.LOG_FILENAME_FORMAT; try { //delete header row dt.Rows[0].Delete(); lblMessage.Text = "uploading..."; Application.DoEvents(); //upload data foreach (DataRow dr in dt.Rows) { if (dr[0].ToString() != "") { //folder structure & file var fullPath = txtArchivePath.Text + dr[0].ToString(); var fileName = dr[1].ToString(); var folderPath = dr[2].ToString().Replace("\\", "/").TrimStart('/'); //extend meta var index1 = dr[3].ToString(); var index2 = dr[4].ToString(); var index3 = dr[5].ToString(); var index4 = dr[6].ToString(); var index5 = dr[7].ToString(); var index6 = dr[8].ToString(); var index7 = dr[9].ToString(); var index8 = dr[10].ToString(); var index9 = dr[11].ToString(); var index10 = dr[12].ToString(); var index11 = dr[13].ToString(); var index12 = dr[14].ToString(); var index13 = dr[15].ToString(); AddFolder(folderPath); AddFile(fullPath, folderPath, fileName , GlobalConst.METADATA_FIELDS.Split(',') , new[] { index1, index2, index3, index4, index5, index6, index7, index8, index9, index10, index11, index12, index13 } , logFileName); } } lblMessage.Text = string.Format("upload success,the log file name is\"{0}\"", logFileName); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void systemSettingsToolStripMenuItem_Click(object sender, EventArgs e) { var frm = new frmSystemSetting(); frm.ShowDialog(); } private void restartToolStripMenuItem_Click(object sender, EventArgs e) { if (MessageBox.Show("confirm restart?", "tips", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { Application.Restart(); } } private void aboutToolStripMenuItem_Click(object sender, EventArgs e) { var frm = new frmAbout(); frm.Show(); } private void logToolStripMenuItem_Click(object sender, EventArgs e) { var frm = new frmLog(); frm._logPath = this._logPath; frm.ShowDialog(); } } }
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="Domain" value="megatest"/> <add key="UserName" value="nick.zhong"/> <add key="Password" value="Mega@data"/> <add key="SiteUrl" value="http://win2012-sp/sites/nick"/> <add key="SiteDocPath" value="/sites/nick/Shared Documents"/> <add key="MetadataFields" value="Updater,UpdateDate,ProfileName,INDEX_1,INDEX_2,INDEX_3,INDEX_4,INDEX_5"/> <add key="LogPath" value="{0}/Log"/> </appSettings> </configuration>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Configuration; namespace SPWidget { public class GlobalConst { public static readonly string SITE_URL = ConfigurationManager.AppSettings["SiteUrl"].ToString(); public static readonly string SITE_DOC_PATH = ConfigurationManager.AppSettings["SiteDocPath"].ToString(); public static readonly string METADATA_FIELDS = ConfigurationManager.AppSettings["MetadataFields"].ToString(); public static readonly string DOMAIN = ConfigurationManager.AppSettings["Domain"].ToString(); public static readonly string USERNAME = ConfigurationManager.AppSettings["UserName"].ToString(); public static readonly string PASSWORD = ConfigurationManager.AppSettings["Password"].ToString(); public static readonly string LOG_PATH = ConfigurationManager.AppSettings["LogPath"].ToString(); public static readonly string LOG_FILENAME_FORMAT = DateTime.Now.ToString("yyyyMMddHHmmss") + ".log"; } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Collections; using System.Configuration; using SP = Microsoft.SharePoint.Client; namespace SPWidget { public partial class frmSystemSetting : Form { public frmSystemSetting() { InitializeComponent(); dgvFieldsInfo.AutoGenerateColumns = false; } private void btnSave_Click(object sender, EventArgs e) { var dicCfg = new Dictionary<string, string>(); dicCfg.Add("SiteUrl", txtSiteUrl.Text); dicCfg.Add("SiteDocPath", txtSiteDocPath.Text); dicCfg.Add("MetaDataFields", txtMetadataFields.Text); dicCfg.Add("Domain", txtDomain.Text); dicCfg.Add("UserName", txtUserName.Text); dicCfg.Add("Password", txtPassword.Text); var cfg = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); foreach (var kvp in dicCfg) { cfg.AppSettings.Settings[kvp.Key].Value = kvp.Value; cfg.Save(); } if (MessageBox.Show("save success, restart?", "tips", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { Application.Restart(); } } private void frmSystemSetting_Load(object sender, EventArgs e) { txtMetadataFields.Text = GlobalConst.METADATA_FIELDS; txtSiteDocPath.Text = GlobalConst.SITE_DOC_PATH; txtSiteUrl.Text = GlobalConst.SITE_URL; txtDomain.Text = GlobalConst.DOMAIN; txtUserName.Text = GlobalConst.USERNAME; txtPassword.Text = GlobalConst.PASSWORD; } private void btnQueryListMeta_Click(object sender, EventArgs e) { lbListName.Items.Clear(); if (txtSiteUrl.Text != "") { var ctx = new SP.ClientContext(txtSiteUrl.Text); ctx.Credentials = new System.Net.NetworkCredential(txtUserName.Text, txtPassword.Text, txtDomain.Text); var list = ctx.Web.Lists; ctx.Load(list); ctx.ExecuteQuery(); foreach (var l in list) { lbListName.Items.Add(l.Title); } } else { MessageBox.Show("please set the site url first", "tips", MessageBoxButtons.OK); } } private void lbListName_SelectedIndexChanged(object sender, EventArgs e) { var selectedItem = lbListName.SelectedItem; var ctx = new SP.ClientContext(txtSiteUrl.Text); ctx.Credentials = new System.Net.NetworkCredential(txtUserName.Text, txtPassword.Text, txtDomain.Text); var list = ctx.Web.Lists.GetByTitle(selectedItem.ToString()); var fieldList = list.Fields; ctx.Load(fieldList); ctx.ExecuteQuery(); var fList = new List<FieldsInfo>(); foreach (var f in fieldList) { fList.Add(new FieldsInfo() { Title = f.Title, InternalName = f.InternalName }); } dgvFieldsInfo.DataSource = fList; } public class FieldsInfo { public string Title { get; set; } public string InternalName { get; set; } } private void dgvFieldsInfo_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { var fieldText = dgvFieldsInfo.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(); txtMetadataFields.Text = txtMetadataFields.Text + "," + fieldText; } private void btnClearFields_Click(object sender, EventArgs e) { txtMetadataFields.Text = string.Empty; } private void btnFormat_Click(object sender, EventArgs e) { var sourceFieldText = txtMetadataFields.Text.Trim(); if (sourceFieldText != "" && (sourceFieldText.IndexOf(",") >= 0 || sourceFieldText.IndexOf(",") >= 0)) { var fieldText = txtMetadataFields.Text.Replace(",", ",").Split(','); var list = new List<string>(); var sb = new StringBuilder(); foreach (var s in fieldText) { if (s != "") { if (!list.Contains(s)) { list.Add(s.Trim()); sb.AppendFormat("{0},", s.Trim()); } } } txtMetadataFields.Text = sb.ToString().TrimEnd(','); } } } }
Ref:http://www.cnblogs.com/jaxu/archive/2011/11/29/2267572.html