Атрибут типа «Документ». Скачивание архива файлов из связанных записей и его прикрепление к атрибуту
Введение
Comindware Platform позволяет прикреплять файлы к атрибуту типа «Документ». При этом из каждой записи прикреплённые файлы приходится скачивать отдельно.
Атрибут типа «Запись» позволяет связать запись с реестром документов, к которым прикреплены файлы.
С помощью C#-скрипта можно настроить кнопку для скачивания из реестра документов в одном архиве всех файлов, связанных с записью.
Также при помощи C#-скрипта можно добавить сформированный архив файлов в атрибут типа «Документ».
Здесь представлен пример настройки кнопки, скачивающей все файлы, которые связаны с текущей записью, и добавляющей этот архив в атрибут типа «Документ».
См. также примеры работы с атрибутом типа «Документ»:
- Клонирование записи вместе с прикреплёнными файлами
- Скачивание файлов в папку на сервере
- Скачивание архива с файлами из выбранных строк таблицы или одной записи
Структура атрибута типа «Документ»
- Атрибут типа «Документ» хранит одну или несколько ссылок на записи (документы) в системном шаблоне документа, к которым прикрепляются файлы (например, загруженные пользователями).
- В шаблоне документа имеется атрибут
currentRevision(текущая версия), который хранит ссылку на запись в системном шаблоне версии. - В шаблоне версии имеются атрибуты
title(имя) иcontent(содержимое), которые хранят имя файла и ссылку на файл, физически хранящийся в папкеStreamsна сервере.
Извлечение файлов из атрибута типа «Документ» с помощью C#
Чтобы считать файл из атрибута типа «Документ» с помощью C#-скрипта, необходимо:
-
из текущей записи получить массив идентификаторов файлов, прикреплённых к атрибуту:
var fileIds = Api.TeamNetwork.ObjectService.GetPropertyValues(recordId, new [] {"documentAttributeSystemName"})`; -
получить массив объектов с прикреплёнными файлами:
var attachedFileObjects = fileIds[docId].TryGetValue("Files", out object fileObject)&& fileObject != null ? fileObject as object[] : null; -
получить объект файла (
attachedFile):var attachedFile = Api.TeamNetwork.DocumentService.GetContent(attachedFileObject[0].ToString()); -
получить имя файла с расширением (
attachedFile.Name); - получить содержимое файла (
attachedFile.Data); -
при необходимости получить объект с метаданными документа:
var attachedFile = Api.TeamNetwork.DocumentService.GetDocument(attachedFileObject[0].ToString());attachedFile.Title— имя файла с расширением;attachedFile.Extension— расширение файла.
Добавление файлов в атрибут типа «Документ» с помощью C#
Чтобы прикрепить к атрибуту типа «Документ» файл с помощью C#-скрипта, необходимо:
-
сформировать объект типа
Document:var document = new Document{Title = "имя файла.расширение",Extension = ".расширение"}; -
сформировать массив байтов
byte[] fileBytesс содержимым файла; -
из массива байтов создать поток
MemoryStream()для прикрепления документа к атрибуту:var fileStream = new MemoryStream();fileStream.Write(fileBytes, 0, fileBytes.Length);fileStream.Seek(0, SeekOrigin.Begin); -
преобразовать поток в объект документа для прикрепления к атрибуту:
string documentObject = Api.TeamNetwork.DocumentService.CreateDocumentWithStream(document, fileStream, ""); -
сформировать словарь из системного имени атрибута и объекта документа:
var documentDict = new Dictionary<string,object>{{ "DocumentAttributeSystemName", documentObject }}; -
прикрепить результирующий документ к атрибуту записи
reсordId:Api.TeamNetwork.ObjectService.EditWithAlias(reсordId, documentDict)
Прикладная задача
Имеется шаблон «Заявки». К заявке можно прикрепить документы — записи из связанного шаблона «Реестр документов». К каждому документу может быть прикреплено несколько файлов.
Необходимо создать кнопку для скачивания архива всех файлов из всех документов, прикреплённых к заявке. Скачанный архив необходимо прикрепить к заявке.
Настройка кнопки для скачивания архива файлов
Чтобы скачать документы и прикрепить их к записи, настройте кнопку и C#-скрипт для неё.
-
Создайте шаблон записи «Реестр документов» со следующим атрибутом:
- Название: Файлы
- Системное имя: Files
- Тип данных: документ
- Использовать для поиска записей: флажок установлен
- Хранить несколько значений: флажок установлен
Внимание!
Для корректного скачивания файлов с помощью C#-скрипта у атрибута типа «Документ» рекомендуется установить флажок «Использовать для поиска записей». В противном случае скрипт может не сработать.
-
Создайте шаблон записи «Заявки» со следующими атрибутами:
Название Системное имя Тип данных Свойства Документы Documents Запись - Связанный шаблон: Реестр документов
- Хранить несколько значений: флажок установлен
Архив документов DocumentArchive Документ -
Создайте кнопку «Скачать архив документов» со следующими свойствами:
- Контекст операции: запись;
- Операция: С#-скрипт;
- Результат выполнения: скачать документ.
Контекст C#-скрипта
C#-скрипты можно использовать в следующих контекстах:
- на кнопках;
- в задачах-выполнении сценария;
- в сценариях.
В зависимости от контекста в C#-скрипте будут отличаться метод
Main()и возвращаемое значение.Чтобы применить описанный выше C#-скрипт в других контекстах, также понадобится изменить значение переменной
reсordId, содержащей ID текущей записи:var reсordId = context.BusinessObjectId;— для задачи-выполнения сценария;var reсordId = userCommandContext.ObjectIds[0];— для кнопки;var reсordId = ObjectId.ToString().Replace("user.", "");— для действия сценария «Проверить результат скрипта».
-
На вкладке «Скрипт» добавьте C#-скрипт по следующему образцу:
Скрипт для скачивания файлов из связанных записейusing System;using System.Collections.Generic;using System.IO;using Comindware.Data.Entity;using Comindware.TeamNetwork.Api.Data.UserCommands;using Comindware.TeamNetwork.Api.Data;using System.Collections.Generic;using System.Linq;class Script{// Определяем конструктор скрипта, выполняющегося в контексте кнопкиpublic static UserCommandResult Main(UserCommandContext userCommandContext, Comindware.Entities entities){// Получаем ID текущей записи шаблона «Заявки» из контекста операции кнопки.var reсordId = userCommandContext.ObjectIds[0];// Помещаем в массив documentIds идентификаторы записей шаблона «Реестр документов»// из атрибута «Документы» текущей записи.// Documents — системное имя атрибута «Документы» шаблона «Заявки».var documentIds = Api.TeamNetwork.ObjectService.GetPropertyValues(new string[] {reсordId}, new [] {"Documents"});// По идентификаторам получаем массив записей шаблона «Реестр документов», связанных с текущей записью.var DocumentRecords = documentIds[reсordId].TryGetValue("Documents", out object OutputRecordArray) && OutputRecordArray != null ? OutputRecordArray as object[] : null;// Инициализируем словарь файлов для архива в виде пар «имя:содержимое».var files = new Dictionary<string, byte[]>();// Добавляем файлы в поток для дальнейшего архивирования// из каждой записи шаблона «Реестр документов».foreach (var DocumentRecord in DocumentRecords){// Получаем идентификатор записи шаблона «Реестр документов».var docId = DocumentRecord.ToString();// Помещаем в массив fileIds идентификаторы файлов, прикреплённых к атрибуту «Файлы».// Files — системное имя атрибута «Файлы» шаблона «Реестр документов».var fileIds = Api.TeamNetwork.ObjectService.GetPropertyValues(new []{docId}, new [] {"Files"});// По идентификаторам получаем массив объектов с прикреплёнными файлами.var attachedFileObjects = fileIds[docId].TryGetValue("Files", out object fileObject)&& fileObject != null ? fileObject as object[] : null;if(attachedFileObjects.Length > 0){// Добавляем в словарь все файлы, прикреплённые к атрибуту «Файлы».foreach(var attachedFileObject in attachedFileObjects){// Получаем прикреплённый файл.var attachedFile = Api.TeamNetwork.DocumentService.GetContent(attachedFileObject.ToString());// Помещаем содержимое файла в словарь файлов для архива по имени.files[attachedFile.Name] = attachedFile.Data;}}}// Формируем архив файлов для скачивания из словаря files.var resultingArchive = Api.TeamNetwork.DocumentService.GetZippedStreams(files);// Инициализируем документ для файла архива,// чтобы прикрепить его к атрибуту «Архив документов».var archiveDocument = new Document{Title = "Data.zip",Extension = ".zip"};// Помещаем архив файлов в массив байтов// для преобразования в документ и прикрепления к атрибуту.byte[] compressedBytes = resultingArchive.ToArray();// Создаём поток для прикрепления документа с архивом к атрибуту.var archiveFileStream = new MemoryStream();archiveFileStream.Write(compressedBytes, 0, compressedBytes.Length);archiveFileStream.Seek(0, SeekOrigin.Begin);// Преобразуем поток в объект документа с архивом для прикрепления к атрибуту.string documentObject = Api.TeamNetwork.DocumentService.CreateDocumentWithStream(archiveDocument, archiveFileStream, "");// Формируем словарь для прикрепления документа с архивом к атрибуту.var documentDict = new Dictionary<string,object>{// DocumentArchive — системное имя атрибута «Архив документов».{ "DocumentArchive", documentObject }};// Прикрепляем архив к атрибуту «Архив документов».Api.TeamNetwork.ObjectService.EditWithAlias(reсordId, documentDict);// Возвращаем архив для скачивания в качестве результата нажатия кнопки.return new UserCommandResult{Success = true,Commited = true,File = new UserCommandFileResult{Content = resultingArchive,// Укажите имя архиваName = archiveDocument.Title}};}} -
Поместите на форму шаблона «Заявки» атрибут «Архив документов» и кнопку «Скачать архив документов».
- Поместите на форму атрибут «Документы» и настройте его представление в виде таблицы.
- Поместите в таблицу «Документы» на форме атрибут «Файлы» шаблона записи «Реестр документов».
- В область кнопок таблицы «Документы» поместите кнопки «Создать».
Тестирование
- Создайте новую запись в шаблоне «Заявки».
- Добавьте несколько строк в таблицу «Документы».
- К каждой строке в таблице «Документы» прикрепите несколько файлов (в столбце «Файлы»).
- Сохраните запись.
- Нажмите кнопку «Скачать архив документов».
-
Браузер скачает архив со всеми файлами из документов, прикреплённых к заявке.
Примечание
Если в браузере отобразится сообщение «Незащищенное скачивание заблокировано», нажмите кнопку «Сохранить», чтобы продолжить скачивание.
-
В поле «Архив документов» должен появиться архив со всеми файлами из документов, прикреплённых к заявке.