Оптимизация экспорта в PDF огромных отчетов в Sql Reporting Services 2005

Во-первых, я понимаю, что запускать очень большие / длинные отчеты - ужасная идея. Я знаю, что у Microsoft есть эмпирическое правило, согласно которому отчет SSRS должен выполняться не более 30 секунд. Однако иногда гигантские сообщения являются предпочтительным злом из-за внешних сил, таких как соблюдение государственных законов.

На моем месте работы у нас есть приложение asp.net (2.0), которое мы перевели с Crystal Reports на SSRS. Из-за большой базы пользователей и сложных требований к пользовательскому интерфейсу отчетности у нас есть набор экранов, которые принимают параметры, введенные пользователем, и создают расписания, которые будут выполняться в ночное время. Поскольку приложение поддерживает несколько платформ отчетности, мы не используем средства планирования / создания моментальных снимков SSRS. Все отчеты в системе создаются с помощью запланированного консольного приложения, которое принимает параметры, введенные пользователем, и генерирует отчеты с соответствующими решениями для создания отчетов, с помощью которых были созданы отчеты. В случае отчетов SSRS консольное приложение создает отчеты SSRS и экспортирует их в виде PDF-файлов через API веб-службы SSRS.

До сих пор работать с SSRS было намного проще, чем с Crystal, за исключением определенного отчета на 25 000 страниц, который мы недавно преобразовали из отчетов Crystal в SSRS. Сервер SSRS - это 64-битный сервер 2003 с 32 гигабайтами оперативной памяти, на котором работает SSRS 2005. Все наши меньшие отчеты работают фантастически, но у нас возникают проблемы с нашими большими отчетами, такими как этот. К сожалению, мы не можем создать вышеупомянутый отчет через API веб-службы. Следующая ошибка возникает примерно через 30-35 минут после создания / экспорта:

Сообщение об исключении: базовое соединение было закрыто: при получении произошла непредвиденная ошибка.

Вызов веб-службы - это то, что, я уверен, вы все видели раньше:

data = rs.Render(this.ReportPath, this.ExportFormat, null, deviceInfo,
   selectedParameters, null, null, out encoding, out mimeType, out usedParameters, 
   out warnings, out streamIds);

Странно то, что этот отчет будет запускаться / обрабатываться / экспортироваться, если отчет запускается непосредственно на сервере отчетов с помощью диспетчера отчетов. Процесс, который создает данные для отчета, работает около 5 минут. Отчет отображается в собственном формате SSRS в браузере / средстве просмотра примерно через 12 минут. Экспорт в pdf через браузер / программу просмотра в диспетчере отчетов занимает дополнительно 55 минут. Это работает надежно и дает колоссальный PDF-файл размером 1,03 ГБ.

Вот некоторые из наиболее очевидных вещей, которые я пытался заставить отчет работать через API веб-службы:

  • установите значение HttpRuntime ExecutionTimeout на 3 часа на сервере отчетов
  • отключен http keep alives на сервере отчетов
  • увеличено время ожидания скрипта на сервере отчетов
  • установить для отчета никогда не истекать тайм-аут на сервере
  • установить таймаут отчета на несколько часов по вызову клиента

Судя по настройкам, которые я пробовал, я с уверенностью могу сказать, что все проблемы с тайм-аутом были устранены.

Основываясь на моем исследовании сообщения об ошибке, я считаю, что API веб-службы по умолчанию не отправляет фрагментированные ответы. Это означает, что он пытается отправить по сети все 1,3 ГБ за один ответ. В какой-то момент IIS сдастся. К сожалению, API абстрагирует конфигурацию веб-службы, поэтому я не могу найти способ включить разбиение ответа.

  1. Кто-нибудь знает, как можно уменьшить / оптимизировать фазу экспорта PDF и / или размер PDF без снижения общего количества страниц?
  2. Есть ли способ включить фрагментацию ответа для SSRS?
  3. Есть ли у кого-нибудь еще какие-нибудь теории относительно того, почему это работает на сервере, а не через API?

РЕДАКТИРОВАТЬ: После прочтения сообщения kcrumley я начал смотреть на средний размер страницы, беря размер файла / количество страниц. Достаточно интересно, что в небольших отчетах математика получается так, что каждая страница составляет примерно 5 КБ. Интересно, что при увеличении отчета это «среднее» увеличивается. Например, отчет на 8000 страниц в среднем составляет более 40 КБ на страницу. Очень странно. Я также добавлю, что количество записей на страницу устанавливается за исключением последней страницы в каждой группировке, поэтому это не тот случай, когда на одних страницах больше записей, чем на других.

Ответов (3)

Очевидно, это огромный отчет, на самом деле он ближе к базе данных 1,3 ГБ, чем к отчету.

Вы думали найти способ разделить его на несколько частей, а затем объединить их вместе? (используйте один из нескольких способов объединения PDF-файлов, перечисленных на этом сайте.)

Мы сузили экспорт больших PDF-файлов из SSRS и обнаружили 2 основных виновника.

1) Если изображения не имеют цветовой тип 3 в формате JPG или PNG, они расширяются до BMP. См. Здесь.

2) Если вы не настроите SSRS на иное (не рекомендуется), тогда SSRS будет встраивать шрифты или подмножества шрифтов в PDF, если они не являются одним из 5 «стандартных» шрифтов PDF .

Хотя ни один из стандартных шрифтов (кроме Symbol, я полагаю) не установлен в большинстве ОС Windows из коробки, мы обнаружили, что если вы используете их, Times New Roman, Courier New, or Arial прямая и обратная подстановка шрифтов будет иметь место.

Самый простой способ преобразовать ваши RDL - это просмотреть их как XML, выполнить поиск и заменить FontFamily теги.

Если вам придется использовать нестандартный шрифт, вы все равно можете минимизировать ущерб:

  • Используйте как можно меньше шрифтов. Выполните поиск в RDL XML, чтобы убедиться, что нет лишних шрифтов.
  • Используйте шрифты TTF, если вы используете разные размеры шрифта.
  • Старайтесь не смешивать обычные, полужирные и курсивные варианты шрифта, иначе он будет встраиваться несколько раз.
  1. Кто-нибудь знает, как можно уменьшить / оптимизировать фазу экспорта PDF и / или размер PDF без снижения общего количества страниц?

У меня есть несколько идей и вопросов:
1. Это отчет с большим количеством графики? Если нет, есть ли у вас таблицы, которые начинаются как текст, но преобразуются в графику средством рендеринга SSRS PDF (проверьте, можете ли вы выделить текст в PDF)? 41 КБ на страницу может быть больше, чем должно быть, а может и нет, в зависимости от того, насколько насыщен информацией ваш отчет. Но у нас были случаи, когда у нас были незначительные проблемы с макетом отчета, например, когда таблица выходила за край страницы, что приводило к тому, что средство визуализации PDF SSRS «вскидывало руки» и отображало таблицу как изображение, а не как текст. . Очевидно, что чем меньше графиков в вашем отчете, тем меньше будет размер вашего файла.
2. Есть ли способ легко разбить отчет на части? Например, если это отчет с 10 местоположениями, где после местоположения 1 следует местоположение 2 и т. Д., В вашем окончательном отчете, можете ли вы запустить часть местоположения 1 независимо от части местоположения 2 и т. Д.? Если это так, вы можете объединить 10 подотчетов в один окончательный PDF-файл с помощью PDFSharp после того, как получите их все. Это приводит к некоторым трудностям с нумерацией страниц, но ничего непреодолимого.

3. Есть ли у кого-нибудь еще какие-нибудь теории относительно того, почему это работает на сервере, а не через API?

Я предполагаю, что это будет размер отчета. Я не помню всего, что такое настройка IIS и что специфично для SSRS, но могут быть некоторые общие настройки IIS (возможно, в Metabase.xml), которые вам придется обновить, чтобы даже позволить прохождение такого большого количества данных.

Вы можете изолировать вопрос о том, является ли время проблемой, взяв один из ваших рабочих отчетов и построив долгое время ожидания в ваших хранимых процедурах с помощью WAITFOR (при условии, что SQL Server для вашей СУБД).

Не решения как таковые, а идеи. Надеюсь, это поможет.