Загрузка данных из Excel в список SharePoint 2013. Удаление элементов списка с помощью Excel. Выгрузка элементов списка в Excel

от автора

Я – студент старших курсов одного из столичных технических вузов, который по долгу службы тесно связан с настройкой и разработкой корпоративных порталов на платформе SharePoint 2013. В этой статье я хочу рассказать и показать, как можно с помощью Excel файла наполнить и очистить список SharePoint, а также выгрузить необходимое содержимое.

А зачем это, собственного говоря, надо? Давайте представим ситуацию, что у нас есть крупная организация «Бендер и Ко», которая включает в себя некоторое число независимых филиалов, для простоты эксперимента ограничимся двумя – «Рога» и «Копыта». Организации быстро растут, приходят новые сотрудники, нужно вносить о них информацию, содержащую порядка 10 атрибутов. Времени на занесение 2-3 человек в список SharePoint вручную много не потребуется, а если таких 20 или 50? Да и Excel пользователям пока ближе, чем SharePoint. Таким образом, с целью экономии времени, я предлагаю экспортировать данные из Excel.

Импорт, экспорт и удаление данных будем осуществлять с помощью собственной веб-части SharePoint.

Итак, поехали.

1. Создаем список «Сотрудники» в SharePoint и подготавливаем шаблон Excel документа для загрузки пользователей

Мой список, выглядит вот так:

Прошу обратить внимание, что данные 3 элемента являются папками, внутрь которых мы будем добавлять сотрудников.

А шаблон Excel — вот так:

Стоит обратить внимание на то, что тип данных столбца в списке SharePoint должен совпадать с типом данных соответствующего атрибута в документе Excel. Я все поля сделал текстовыми.

2. Создаем проект SharePoint 2013

New Project -> SharePoint Solutions -> SharePoint 2013 — Empty Project -> ОК.

Далее указываем узел, выбираем Deploy as a farm solution и нажимаем Finish.

Следующим шагом необходимо добавить Visual Web Part. Клик правой кнопкой мыши на решение -> Add -> New Item -> Visual Web Part -> Add.

3. Разрабатываем внешний вид веб-части

За внешний вид отвечает файл .ascx, который открывается перед нами сразу после нажатия кнопки Add из предыдущего пункта. В своем примере я ограничусь 2 лейблами для вывода информации в ходе работы веб-части; элементом FileUpload, который позволит выбрать файл для загрузки; DropDownList — выпадающий список, содержащий главную организацию и филиалы; 3 кнопки для добавления, удаления и экспорта элементов списка. После добавления следующего кода:

<asp:Label ID="Label1" runat="server" Text="" EnableViewState="false"></asp:Label> <asp:Label ID="Label2" runat="server" Text=""></asp:Label> <div id="dvSource" runat="server">    	<fieldset style="width:51%; max-width:600px; min-width:600px;">    	<legend></legend>    	<table>        	<tr>            	<td>Выберите Excel файл :  </td>            	<td>                	<asp:FileUpload ID="FileUpload1" runat="server" Width="453px" />            	</td>         	</tr>         	<tr>            	<td>Выберите филиал : </td>            	<td>                	<asp:DropDownList ID="DropDownList1" runat="server" Width="238px">                	<asp:ListItem Enabled="true" Text="" Value="-1"></asp:ListItem>                    	<asp:ListItem Text="Бендер и Ко" Value="1"></asp:ListItem>                    	<asp:ListItem Text="Рога" Value="2"></asp:ListItem>                    	<asp:ListItem Text="Копыта" Value="3"></asp:ListItem>                	</asp:DropDownList>            	</td>        	</tr>         	</table> <div style="float:left; margin-top:20px; width:80%; margin-left:122px">    <asp:Button ID="Button1" runat="server" OnClick="btnUpload_Click" Text="Загрузить данные"  />    <asp:Button ID="Button2" runat="server" OnClick="btnRemove_Click" Text="Загрузить данные на удаление" />    <asp:Button ID="Button3" runat="server" OnClick="btnUnload_Click" Text="Выгрузить данные в Excel"  />            	</div> 	</fieldset> </div> 

Мы получим вот такую веб-часть:

4. В файле .webpart, если необходимо, меняем Title и Description веб-части

5. Подключаем библиотеку EPPlus

Для того, чтобы работать с документами Excel скачаем и добавим к проекту .net библиотеку EPPlus. Клик правой кнопкой мыши на решение -> Add Reference -> Browse -> Выбираем EPPlus.dll -> OK.

Также необходимо добавить EPPlus.dll в wsp пакет. Левой кнопкой мыши двойной клик на папку Package -> Advanced -> Add -> Add Existing Assembly -> Выбираем EPPlus.dll -> OK.

Последний шаг состоит в подключении

using OfficeOpenXml; using Microsoft.SharePoint; using System.IO; using System.Collections.Generic;

в файл .ascx.cs.

6. Пишем функциональный код

6.1. Создаем связь между полями документа Excel и столбцами списка SharePoint с помощью Dictionary
private Dictionary<int, string> GetColumnMapping()    { 	       	Dictionary<int, string> map = new Dictionary<int, string>(); 	       	map.Add(0, "ИД"); 	       	map.Add(1, "ФИО"); 	       	map.Add(2, "Должность"); 	       	map.Add(3, "E-mail"); 	       	map.Add(4, "Номер факса"); 	       	map.Add(5, "Внутренний номер"); 	       	map.Add(6, "Служебный телефон"); 	       	map.Add(7, "Адрес"); 	       	map.Add(8, "Номер сотрудника"); 	       	map.Add(9, "День рождения");  	       	return map;    } 

Первым параметром при вызове метода Add является индекс столбца в таблице Excel, вторым — Display Name столбца в списке SharePoint.

Теперь мы полностью готовы к написанию основного кода.

6.2. Обработка события при нажатии на кнопку «Загрузить данные»

protected void btnUpload_Click(object sender, EventArgs e)         {             if (!FileUpload1.HasFile)             {                 Label1.Text = "Вы не выбрали Excel файл!";                 return;             }             try             {                 string Url = SPContext.Current.Web.Url;                 using (SPSite spSite = new SPSite(Url))                 {                     using (SPWeb spWeb = spSite.OpenWeb())                     {                         spWeb.AllowUnsafeUpdates = true;                         SPList list = spWeb.Lists["Сотрудники"];                         var folderDZO = list.RootFolder.SubFolders[DropDownList1.SelectedItem.Text].ToString();                         SPFolder folder = spWeb.GetFolder(folderDZO);                                     string LoginName = SPContext.Current.Web.CurrentUser.LoginName;                          if (CheckPermission(LoginName, folder.Item, spWeb) == false)                         {                             Label2.Text += "У Вас нет доступа на редактирование элементов данной папки!";                             return;                         }                         else                         {                             try                             {                                 byte[] fileData = FileUpload1.FileBytes;                                 using (MemoryStream memStream = new MemoryStream(fileData))                                 {                                     memStream.Flush();                                     using (ExcelPackage pck = new ExcelPackage(memStream))                                     {                                         if (pck != null)                                         {                                             CreateListItem(pck, list, spWeb);                                         }                                     }                                 }                                  Label1.Text = "Данные успешно загружены...";                             }                             catch (Exception Ex1)                             {                                 Label1.Text = "Возникла ошибка   " + Ex1.Message;                             }                         }                     }                 }             }             catch (Exception Ex)             {                 Label1.Text = "Возникла ошибка   " + Ex.Message;             }         } 

Как я уже говорил в самом начале, организация включает в себя главную организацию и 2 филиала. Естественно предположить, что администраторы, добавляющие сотрудников в свои филиалы, будут разными, следовательно, у папок будут уникальные права доступа. Таким образом, прежде чем выполнить операцию создания элемента, неплохо бы убедиться в том, что у нас есть права на изменение элементов конкретной папки. Проверку осуществляет простенькая функция CheckPermission.

public static bool CheckPermission(string userName, SPListItem folders, SPWeb spWeb)         {             bool perm = false;             SPUser oUser = spWeb.CurrentUser;             perm = (bool)folders.DoesUserHavePermissions(oUser, SPBasePermissions.EditListItems);             return perm;         } 

Все возможные значения параметра SPBasePermissions вы может просмотреть тут.

Далее используется функция CreateListItem, которая непосредственно производит добавление пользователя.

private void CreateListItem(ExcelPackage pck, SPList list, SPWeb spWeb)         {             Dictionary<int, string> column = GetColumnMapping();             ExcelWorksheet ws = pck.Workbook.Worksheets[1];             int rowCount = ws.Dimension.End.Row + 1;             int colCount = ws.Dimension.End.Column + 1;             var folderDZO = list.RootFolder.SubFolders[DropDownList1.SelectedItem.Text];             SPListItemCollection itemColl = list.Items;              for (int i = 2; i < rowCount && ws.Cells[i, 1].Value != null; i++)             {                 if (IsPeople(ws.Cells[i, 1].Value.ToString(), list) == false)                 {                                      SPListItem item = list.AddItem(folderDZO.ServerRelativeUrl, SPFileSystemObjectType.File, null);                     for (int j = 1; j < colCount; j++)                     {                         if (column.ContainsKey(j))                             item[column[j]] = ws.Cells[i, j].Value.ToString();                     }                     item.Update();                 }                 else Label2.Text += " Пользователь " + ws.Cells[i, 1].Value.ToString() + " не был добавлен, поскольку он уже существует!";             }         } 

Внутри этого метода мы обращаемся к функции IsPeople, которая проверяет не был ли данный пользователь добавлен ранее.

public static bool IsPeople(string fio, SPList list)         {                        foreach (SPListItem item in list.Items)             {                 if (item["ФИО"].ToString() == fio)                     return true;             }              return false;         } 

Поскольку я знаю, что людей с одинаковой фамилией, именем и отчеством в моем примере нет, то в качестве атрибута для проверки я выбрал столбец ФИО. В реальной же ситуации необходимо выбрать столбец, который однозначно подчеркнет уникальность записи, например, E-mail.

6.3. Обработка события при нажатии на кнопку «Загрузить данные на удаление»

Непосредственно обработка точно такая же как и в предыдущем пункте. Однако функция CreateListItem немного модифицирована.

private void RemoveListItem(ExcelPackage pck, SPList list, SPWeb spWeb)         {             Dictionary<int, string> column = GetColumnMapping();             ExcelWorksheet ws = pck.Workbook.Worksheets[1];             int rowCount = ws.Dimension.End.Row + 1;             int colCount = ws.Dimension.End.Column + 1;             var folderDZO = list.RootFolder.SubFolders[DropDownList1.SelectedItem.Text];             SPListItemCollection itemColl = list.Items;              for (int i = 2; i < rowCount && ws.Cells[i, 1].Value != null; i++)             {                 if (IsPeople(ws.Cells[i, 1].Value.ToString(), list) == true)                 {                                         foreach (SPListItem item in list.Items)                     {                         if (ws.Cells[i, 1].Value.ToString() == item["ФИО"].ToString())                         {                             item.Delete();                             break;                         }                     }                     list.Update();                 }                 else Label2.Text += " Пользователь " + ws.Cells[i, 1].Value.ToString() + " не был удален, поскольку его не существует!";             }         } 

6.4. Обработка события при нажатии на кнопку «Выгрузить данные в Excel»

 protected void btnUnload_Click(object sender, EventArgs e)         {             string Url = SPContext.Current.Web.Url;             using (SPSite spSite = new SPSite(Url))             {                 using (SPWeb spWeb = spSite.OpenWeb())                 {                     spWeb.AllowUnsafeUpdates = true;                     SPList list = spWeb.Lists["Сотрудники"];                     SPFolder folder = list.RootFolder.SubFolders[DropDownList1.SelectedItem.Text.ToString()];                      SPQuery query = new SPQuery();                     query.Folder = folder;                     SPListItemCollection listitem = list.GetItems(query);                      ExcelPackage pck = new ExcelPackage();                     var ws = pck.Workbook.Worksheets.Add("Сотрудники");                      int rowIndex = 1;                     ws.Cells[rowIndex, 1].Value = "ИД";                     ws.Cells[rowIndex, 2].Value = "ФИО";                     ws.Cells[rowIndex, 3].Value = "Должность";                     ws.Cells[rowIndex, 4].Value = "E-mail";                     ws.Cells[rowIndex, 5].Value = "Номер факса";                     ws.Cells[rowIndex, 6].Value = "Внутренний номер";                     ws.Cells[rowIndex, 7].Value = "Служебный телефон";                     ws.Cells[rowIndex, 8].Value = "Адрес";                     ws.Cells[rowIndex, 9].Value = "Номер сотрудника";                     ws.Cells[rowIndex, 10].Value = "Дата рождения";                     rowIndex++;                                 for (int i = 0; i < listitem.Count; i++)                     {                         SPListItem item = listitem[i];                         ws.Cells[rowIndex, 1].Value = item["ИД"];                         ws.Cells[rowIndex, 2].Value = item["ФИО"];                         ws.Cells[rowIndex, 3].Value = item["Должность"];                         ws.Cells[rowIndex, 4].Value = item["E-mail"];                         ws.Cells[rowIndex, 5].Value = item["Номер факса"];                         ws.Cells[rowIndex, 6].Value = item["Внутренний номер"];                         ws.Cells[rowIndex, 7].Value = item["Служебный телефон"];                         ws.Cells[rowIndex, 8].Value = item["Адрес"];                         ws.Cells[rowIndex, 9].Value = item["Номер сотрудника"];                         ws.Cells[rowIndex, 10].Value = item["День рождения"];                         rowIndex++;                     }                      pck.SaveAs(this.Page.Response.OutputStream);                     this.Page.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";                     this.Page.Response.AddHeader("content-disposition", "attachment;  filename=List_of_Employees_as_on_" + DateTime.Now.ToString("dd_MMM_yyyy_HH_mm_ss") + ".xlsx");                     this.Page.Response.Flush();                     this.Page.Response.End();                                }           }       } 

На этом кодить закончили.

7. Развернем решение и добавим веб-часть на страницу

Сначала убедимся, что наш элемент Visual Web Part добавлен в фичу. В окне Solution Explorer переходим в папку Feature и двойной клик по Feature1. Если элемент уже добавлен в фичу — Items in the Feature, то можно идти дальше, если нет – нужно переместить элемент из левого окошка в правое.

Далее правой кнопкой мыши кликаем на решение ->Deploy. Дожидаемся сообщения Deploy succeeded. Теперь решение развёрнуто на портале. Веб-часть располагается в папке Custom.

8. Проверим работу веб-части

8.1. Добавим сотрудников

8.2. Протестировать удаление можно шаблоном, который мы использовали в предыдущем пункте

8.3. Выгрузим сотрудников

Заключение. Потратив некоторое время на разработку веб-части, мы значительно сэкономили время администраторов филиалов, которым пришлось бы вручную заносить сотрудников в список. Таким образом, кнопочная форма и Excel сделали работу SharePoint еще проще и быстрее.

Решение можно скачать тут.

Спасибо за внимание.

ссылка на оригинал статьи http://habrahabr.ru/post/262147/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *