public override void Create(Stream output, GroupReport report) { GroupReport singleReport; List <Instance> instanceList; var contentFolder = Path.Combine(TemporaryDirectory, "files"); var archive = Path.Combine(TemporaryDirectory, "report.zip"); if (!Directory.Exists(TemporaryDirectory)) { Directory.CreateDirectory(TemporaryDirectory); } if (File.Exists(archive)) { File.Delete(archive); } if (!Directory.Exists(contentFolder)) { Directory.CreateDirectory(contentFolder); } else { foreach (var file in Directory.GetFiles(contentFolder)) { File.Delete(file); } } var i = 1; foreach (var instance in report.Instances) { #if f var property = instance.Properties.FirstOrDefault(item => item.Field.Attribute.Naming); string name; if (property != null && property.Value != null) { name = property.Value.ToString(); } else { name = instance.GetHashCode().ToString("X8"); } #warning Путь может соодержать недопустимые символы (ArgumentException). using (var stream = File.Create(Path.Combine(contentFolder, name + ".docx"))) { singleReport = new SingleReport(report.Template, instance); ReportBuilder.Create(stream, singleReport); } #else var validName = instance.FullName.Replace('\\', ' ').Replace('/', ' ').Replace('"', ' '). Replace('*', ' ').Replace(':', ' ').Replace('<', ' ').Replace('>', ' ').Replace('?', ' ') .Replace('|', ' ').Replace('\n', ' '); validName = validName.Trim(); var path = Path.Combine(contentFolder, "№" + i + ". " + validName.Substring(0, Math.Min(120, validName.Length)) + ".docx"); using (var stream = File.Create(path)) { instanceList = new List <Instance>(); instanceList.Add(instance); singleReport = new GroupReport(report.Template, instanceList); ReportBuilder.Create(stream, singleReport); } #endif i++; } Archivator.Create(contentFolder, archive); using (var stream = File.OpenRead(archive)) stream.CopyTo(output); }
public void Create(Stream output, SingleReport report) { if (output == null) { throw new ArgumentNullException("output", Message.Get("Common.NullArgument", "output")); } if (report == null) { throw new ArgumentNullException("report", Message.Get("Common.NullArgument", "report")); } // Открываем содержимое в памяти. var content = report.Template.Content; using (var memory = new MemoryStream()) { memory.Write(content, 0, (int)content.Length); try { Document = WordprocessingDocument.Open(memory, true); Document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document); } #warning TODO Посмотреть актуальные исключения на операции. catch (Exception ex) { throw new InvalidOperationException("Возникла ошибка при чтении тела шаблона.\n", ex.InnerException); } var properties = report.Instance.Properties; var baseProperties = report.Instance.BaseProperties; bool useBaseProperties = baseProperties != null; // Получаем список закладок... var placeholders = Document.ContentControls(); if (placeholders.Count() == 0) { Document.Close(); throw new InvalidOperationException("В теле шаблона не найдено Structured Document Tag элементов."); } foreach (var placeholder in placeholders) { var placeholderId = placeholder.GetSdtTagText(); object entityId, hashedAttributeId, formatId; var uid = new UniqueIDCreator(); uid.Split(placeholderId, out entityId, out hashedAttributeId, out formatId); // В случае отсутствия value - оставлять элемент с оригинальным текстом, но выделять красным шрифтом. if (!useBaseProperties) { if (properties.First(x => x.Field.Attribute.ID.ToString() == hashedAttributeId.ToString()).Value == null) { (placeholder as SdtElement).SetSdtTextColor("FF0000"); } else { // Заполняем try { var value = properties .Where( x => (x.Field.Attribute.ID.ToString() == hashedAttributeId.ToString()) && (x.Field.Format.ID.ToString() == formatId.ToString()) ) .First().Value; var element = placeholder as SdtElement; element.SetSdtText(value.ToString()); element.SetSdtTextColor("000000"); } catch (InvalidOperationException ex) { Document.Close(); throw new InvalidOperationException(String.Format("Не удалось найти атрибут.\n{0}.", ex.Message)); } } } else { var property = baseProperties.First(x => x.Attribute.ID.ToString() == hashedAttributeId.ToString()); if (property.Value == null || property.Value is DBNull) { (placeholder as SdtElement).SetSdtTextColor("FF0000"); } else { try { var element = placeholder as SdtElement; var format = property.Attribute.Type.GetAccessibleFormats(). First(o => o.ID.ToString() == formatId.ToString()); element.SetSdtText(string.Format(format.Provider, format.FormatString, property.Value)); element.SetSdtTextColor("000000"); } catch (InvalidOperationException ex) { Document.Close(); throw new InvalidOperationException(String.Format("Не удалось найти атрибут.\n{0}.", ex.Message)); } } } #warning Неплохо бы выводить сведения о хеше. } Document.Close(); // Результат - пишем в поток. try { memory.Seek(0, SeekOrigin.Begin); memory.CopyTo(output); } catch (NotSupportedException ex) { throw new InvalidOperationException(String.Format("Поток назначения не поддерживает запись:\n{0}.", ex.Message)); } catch (ObjectDisposedException ex) { throw new InvalidOperationException(String.Format("Поток назначения был преждевременно закрыт:\n{0}.", ex.Message)); } catch (IOException ex) { throw new InvalidOperationException(String.Format("Возникла общая ошибка ввода-вывода:\n{0}.", ex.Message)); } } }