예제 #1
0
        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));
                }
            }
        }