Как повторить заголовок группы таблиц на каждой странице в SSRS при выводе в документы [Word]? - PullRequest
1 голос
/ 24 февраля 2020

Как упомянуто в Документация MS :

Word не повторяет строки заголовка на второй странице и выше, хотя вы устанавливаете свойство RepeatOnNewPage строки заголовка stati c в таблице (таблица, матрица или список), чтобы True. Вы можете определить явные разрывы страниц в своем отчете, чтобы строки заголовка появлялись на новых страницах. Однако поскольку Word применяет свою собственную нумерацию страниц к визуализированному отчету, экспортированному в Word, результаты могут отличаться, и строка заголовка может не повторяться предсказуемо. Заголовок stati c - это строка, содержащая заголовки столбцов.

  • Повтор заголовка группы на каждой странице работает только для документов PDF
  • Документы Word могут повторяться только между группами

Так как повторить заголовки групп на каждой странице при выводе документов SSRS в Word?

1 Ответ

2 голосов
/ 24 февраля 2020

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

Кто также может найти это полезным

  • Выходные документы Word с Dynami c Заголовок раздела
  • Порт Отчет SSRS в Word Откройте XML типы файлов, такие как docm, dotx, dotm ...

Ограничения:

  • Поддерживается только XML форматированный файл ( .docx для SSRS ), ограниченный Открыть XML
  • Размер отчета < ~ = 32 МБ (текст), ограничено форматом docx
  • Увеличена стоимость времени генерации отчета
  • Дополнительные заголовки c необходимо сделать для заголовка, если тот же отчет должен предоставить . PDF формат
  • Заголовок таблицы использует заголовок Раздел
  • Проблема выравнивания, если данные полей приводят к увеличению поля

Допущения:

  • Вы уже успешно подготовили свои сгруппированные данные в Tablix
  • Был сделан разрыв страницы между группами данных

Сводка по решению n:

  1. Подготовьте отчет, указав c идентификатор , что заголовок появится на каждой странице
  2. Отобразите отчет в . DOCX
  3. Подготовьте данные для замены
  4. Откройте отчет, используя Открыть XML
  5. Подготовить Заголовок раздела
  6. Найдите разрыв страницы между группами записей и замените его на Разрыв раздела
  7. Свяжите заголовок раздела с каждым разделом соответственно
  8. Готово

Основные действия

1. Подготовьте отчет, используя указанный c идентификатор, чтобы заголовок появлялся на каждой странице

Поместите и выровняйте заголовок вашей группы и заголовок таблицы в разделе Заголовок (не внутри Tablix)

Report Design Sample

[ GroupHeaderText1 ] - текст заголовка, который вы хотите повторить и различный для каждой группы.

It будет отображаться на каждой странице документа Word.

3. Подготовьте данные к замене

Зависит от вашего отчета и структуры данных, подготовьте данные соответствующим образом.

Пример

public class SampleData
{
    public string GroupHeaderField { get; set; }
    public string Data1 { get; set; }
    public string Data2 { get; set; }
    public string Data3 { get; set; }
}

Часть функции для генерации отчета

ReportViewer rv = new ReportViewer();
ReportDataSource reportDataSource = new ReportDataSource();
reportDataSource.Name = "SampleData";
List<SampleData> dataForReport = GetData();
reportDataSource.Value = dataForReport;
rv.LocalReport.DataSources.Add(reportDataSource);
List<string> lstReplace = new List<string>();
//Prepare the data
foreach (SampleData sa in dataForReport)
{
    if (!lstReplace.Contains(sa.GroupHeaderField))
    {
        lstReplace.Add(sa.GroupHeaderField);
    }
}

lstReplace теперь содержит значение для динамических c групповых заголовков.

5. Подготовьте заголовок раздела

Получите заголовок, который мы подготовили на Шаг 1 в качестве шаблона, мы используем его для Заголовок раздела

WordprocessingDocument wordDoc = WordprocessingDocument.Open(docPath, true);
MainDocumentPart mainDocPart = wordDoc.MainDocumentPart;
HeaderPart defaultHeaderPart = mainDocPart.HeaderParts.FirstOrDefault();

Теперь мы создаем часть заголовка для каждого раздела (группы)

List<string> newSectionHeaderIds = new List<string>();
foreach (string groupHeaderText in lstReplace)
{
    HeaderPart newGroupHeaderPart = mainDocPart.AddNewPart<HeaderPart>();
    string sId = mainDocPart.GetIdOfPart(newGroupHeaderPart);
    Header newHeader = (Header)defaultHeaderPart.Header.Clone();

    foreach (Paragraph p in newHeader.Descendants<Paragraph>())
    {
        foreach (Run r in p.Descendants<Run>())
        {
            foreach (Text t in r.Descendants<Text>())
            {
                t.Text = t.Text.Replace("[GroupHeaderText1]", groupHeaderText);
            }
        }
    }
    newHeader.Save(newGroupHeaderPart);
    newSectionHeaderIds.Add(sId);
}

Этот код в основном

  1. Создание нового заголовка
  2. Сохранить идентификатор для последующего использования для привязки раздела
  3. Клонировать содержимое шаблона в этот заголовок
  4. Заменить идентификатор текстом заголовка группы

Чтобы лучше понять, вы должны использовать Open XML SDK 2.5 для Microsoft Office и изучить структуру документа DOCX.

6. Найдите разрыв страницы между группами записей и замените его разрывом раздела

Заголовки разделов готовы. Теперь создайте несколько разделов.

По умолчанию отчет, сгенерированный SSRS, имеет разрыв страницы между группами.

Нам просто нужно заменить их.

Создать SectionProperties шаблон для создания разделов в Word Document, так что у нас могут быть разные заголовки между группами. (Вы можете изменить PageSize и т. Д. c. Используя это свойство)

SectionProperties defaultProperties = mainDocumentPart.Document.Body.Descendants<SectionProperties>().FirstOrDefault();
defaultProperties.AppendChild(new SectionType { Val = SectionMarkValues.NextPage });

Теперь найдите и замените разрыв страницы

foreach (Paragraph p in document.Body.Descendants<Paragraph>())
{
    foreach (Run r in p.Elements<Run>())
    {
        foreach (Break b in r.Descendants<Break>())
        {
            if (b.Type != null)
            {
                if (b.Type.Value == BreakValues.Page)
                {
                    b.Remove(); //Remove the page break
                    p.Descendants<ParagraphProperties>().FirstOrDefault().AppendChild(defaultProperties.CloneNode(true)); //Replace by a cloned section break
                }
            }
        }
    }
}

Обратите внимание, что свойства, такие как размер страницы, ширина и высота, не зависят от каждого раздела, вы должны установить его в шаге 5

7. Привязать заголовок раздела к каждому разделу соответственно

Помните newSectionHeaderIds Список, который мы создали в Шаг 5 ? Теперь мы связываем их.

int i = 0;
foreach (SectionProperties sp in document.Body.Descendants<SectionProperties>())
{
    //Replace them
    sp.RemoveAllChildren<HeaderReference>();
    sp.PrependChild(new HeaderReference() { Id = newSectionHeaderIds[i], Type = HeaderFooterValues.Default });
    i++;
}

8. Готово

Самый важный шаг из всех ... Сохраните его .

wordDoc.Save();

Вы должны быть хороши с go, дайте мне знать у вас есть вопросы.

...