How to export SQL report to image (jpg, bmp, etc)

Привет всем. Хочу поделиться опытом работы с выгрузкой отчётов в картинки формата jpg. Как мы знаем, SQL Reporting service предлагает нам выгрузку отчётов в различные форматы:

imageСреди этих форматов есть TIFF. Но нам необходимо именно jpeg формат. Для этого нам необходимо воспользоваться  нашими навыками в разработке.

Для этого нам пригодится Visual Studio 2012, знания в построении WCF сервисов, знания в построении Windows сервисов и немного .Framework 4.5.

Сценарий использования следующий: необходимо один раз в сутки генерировать отчёты и выгружать в виде картинок, формата jpg, в определённую директорию. Картинки должны быть определённого размера, формат должен меняться.

 

 

SQL Reporting service предоставляет расширенные возможности по экспорту. Список поддерживаемых форматов можно увидеть здесь - https://msdn.microsoft.com/ru-ru/library/dd283101.aspx.

Тип

Расширение

MIMEType

BMP

bmp

image/bmp

GIF

gif

image/gif

JPEG

jpeg

image/jpeg

PNG

png

image/png

TIFF

tif

image/tiff

EMF

emf

image/emf

EMFPlus

emf

image/emf

Приступим.

Создание WCF сервиса

Для начала создадим проект по шаблону WCF service application.

image

Создадим метод, в который будем передавать входные параметры для формирования картинок.

 [ServiceContract]
    public interface IExportReports
    {
        [OperationContract]
        bool GetDataToExport(string filePath, string fileName, string serverReportsURL,
            string formatImage, string reportPath, string pageWidth, string pageHeight,
                string marginTop, string marginLeft, string marginRight, string marginBottom);
    }

Следующий шаг описываем формат выгружаемого отчёта в созданном методе.

 //Get size for Image
            CultureInfo us = new CultureInfo("en-US");
            string deviceInfo = String.Format(
                  "<DeviceInfo>" +
                  "  <OutputFormat>JPEG</OutputFormat>" +
                  "  <PageWidth>{0}cm</PageWidth>" +
                  "  <PageHeight>{1}cm</PageHeight>" +
                  "  <MarginTop>{2}cm</MarginTop>" +
                  "  <MarginLeft>{3}cm</MarginLeft>" +
                  "  <MarginRight>{4}cm</MarginRight>" +
                  "  <MarginBottom>{5}cm</MarginBottom>" +
                  "</DeviceInfo>", pageWidth, pageHeight, marginTop, marginLeft, marginRight, marginBottom);

OutputFormat определяет формат выгрузки отчётов, остальные параметры опредедляют размеры и положение самого отчёта на картинке.

Далее в референсах подключаем сборку Microsoft.ReportViewer.WebForms.dll, которая отвечает за работу отчётов SQL Reporting service. Создаём объект класа ServerReport и передаём параметры пути к серверу отчётов и пути к самим отчётам.

 ServerReport rep = new ServerReport();
Uri ReportURI = new Uri(serverReportsURL);
rep.ReportServerUrl = ReportURI;
rep.ReportPath = reportPath;

Создаём необходимые параметры для генерации отчётов в нужный нам формат.

 Microsoft.Reporting.WebForms.Warning[] warnings;
string format = "IMAGE";
string encoding = String.Empty;
string mimeType = "image/jpeg";
string extension = "jpeg";
string[] streamids = null;

Далее вызываем метод Render для генерации отчёта.

 //Generate report
Byte[] results = rep.Render(format, deviceInfo, out mimeType, out encoding, out extension, out streamids, out warnings);

И экспортируем его по указанному пути.

 //Read and export to image
using (FileStream stream = File.OpenWrite(filePath + "\\" + fileName + "." + formatImage))
{
    stream.Write(results, 0, results.Length);
}

WCF сервис готов. Для тестирования сервиса можно воспользоваться инструментом WCFClientTool, которая идёт в комплекте с Visual Studio. Теперь необходимо создать Windows сервис, который будет запускаться по плану в определённое время.

 

Создание Windows service.

Для этого нам необходимо запустить Visual Studio и создать новый проект по шаблону Windows Service.

image

Для начала подключим наш созданный WCF сервис. Для этого нам необходимо опубликовать наш WCF сервис на IIS (можно воспользоваться Web Deploy 3.0) и после обратиться к нему через браузер. После того как мы получим отклик от нашего сервиса в виде такого формата:

image

Необходимо через контекстное меню сохранить XML второй ссылки. И этот XML файл добавить в проект Windows сервиса. После этого необходимо добавить новый service reference и указать путь к XML файлу. Обязательно поставить галочку генерации асинхронных методов.

image

Следующий шаг, необходимо открыть файл App.config и добавить ключи для входной информации, чтобы динамически не зашивать в код параметры, которые могут меняться. Например, название сервера отчётов, сами названия отчётов, названия файлов картинок, размеры и т.д.

Как пример,

 <appSettings>
  <add key="filePath" value="C:\\inetpub\\wwwroot\\ExportData\\WcfExportReports\\img" />
  <add key="reportPath" value="/reports/report1;/reports/report2;" />
  <add key="fileName" value="report1;report2;" />
  <add key="serverReportsURL" value="https://server/ReportServer" />
  <add key="formatImage" value="jpg" />
  <add key="endpoint" value="BasicHttpBinding_IExportReports" />
  <add key="pageWidth" value="33.1" />
  <add key="pageHeight" value="16.1" />
  <add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>

Остаётся дело за малым, объявляем переменные и считываем данные из конфигурационного файла:

 //Get parameters from config file
List<string> reportPath = new List<string>(ConfigurationManager.AppSettings["reportPath"].Split(new char[] { ';' }));
List<string> fileName = new List<string>(ConfigurationManager.AppSettings["fileName"].Split(new char[] { ';' }));
string filePath = ConfigurationManager.AppSettings["filePath"].ToString();
string serverReportsURL = ConfigurationManager.AppSettings["serverReportsURL"].ToString();
string formatImage = ConfigurationManager.AppSettings["formatImage"].ToString();
string pageWidth = ConfigurationManager.AppSettings["pageWidth"].ToString();
string pageHeight = ConfigurationManager.AppSettings["pageHeight"].ToString();

И теперь передаём данные в WCF сервис.

 for (int i = 0; i < reportPath.Count; i++ )
{
    SRV.ExportReportsClient sync = new SRV.ExportReportsClient(ConfigurationManager.AppSettings["endpoint"].ToString());
    sync.Open();
    sync.GetDataToExportAsync(filePath, fileName[i].ToString(), serverReportsURL, formatImage, reportPath[i].ToString(), pageWidth, pageHeight, "0", "0", "0", "0");
}

После окончания устанавливаем этот сервис на сервере, используя утилиту installUtil.exe.

Обязательно не забыть -   учётная запись пула, под которым будет работать WCF сервис должна иметь права на сервер отчётов, на место, куда будут записываться файлы картинки.