How to export SQL report to image (jpg, bmp, etc)
Привет всем. Хочу поделиться опытом работы с выгрузкой отчётов в картинки формата jpg. Как мы знаем, SQL Reporting service предлагает нам выгрузку отчётов в различные форматы:
Среди этих форматов есть 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.
Создадим метод, в который будем передавать входные параметры для формирования картинок.
[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.
Для начала подключим наш созданный WCF сервис. Для этого нам необходимо опубликовать наш WCF сервис на IIS (можно воспользоваться Web Deploy 3.0) и после обратиться к нему через браузер. После того как мы получим отклик от нашего сервиса в виде такого формата:
Необходимо через контекстное меню сохранить XML второй ссылки. И этот XML файл добавить в проект Windows сервиса. После этого необходимо добавить новый service reference и указать путь к XML файлу. Обязательно поставить галочку генерации асинхронных методов.
Следующий шаг, необходимо открыть файл 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 сервис должна иметь права на сервер отчётов, на место, куда будут записываться файлы картинки.