На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Создание отчёта в формате WORD (.doc) в программе WPF , Библиотеки, снятие скриншотов с WPF контролов, WPF Toolkit и многое другое
    Здравствуйте уважаемые участники форума на Исходниках. Поздравляю Вас всех с прошедшими праздниками.

    В настоящее время я и мои товарищи разрабатываем коммерческую программу, в основе которой находится имитационное моделирование. Её предметная область не так важна. Важно лишь то, что мы работаем на лицензионном ПО и для решения своих задач так же используем либо лицензионное, либо свободно-распространяемое ПО (второе желательнее).

    По окончании эксперимента (моделирования) у нас есть много данных, которые необходимо визуализировать (в виде текста, таблиц, графиков и диаграмм).

    Сначала я использовал FixedDocument, заполнял его необходимыми данными (говоря простым языком, работал с ним, как с WPF-окном, добавлял в него StackPanel, наполнял его текстовыми метками, графиками и прочим). Затем отображал этот документ в DocumentViewer (где его можно было посмотреть и распечатать).

    В связи с увеличением сложности программы, было принято решение о том, что отчёты стоит формировать в формате WORD (.doc), чтобы можно было их сохранять, редактировать (да и, в общем-то, делать с ними всё, что душе угодно).

    Первый вопрос: как правильно (способов много, под «правильно» я подразумеваю «оптимально») формировать отчёты в формате WORD из нашей программы?

    Мне приглянулась библиотека ExportToRTF .

    Во-первых, она бесплатная (Вы можете посмотреть её исходные коды, или просто проверить её, подключив к проекту соответствующую DLL). Во-вторых – предельно простая. Её функционал «не ахти», но для наших задач – вполне хватит (можно использовать форматированный текст, стили, работать с таблицами и вставлять картинки). В-третьих, насколько я понял, она не требует установленного на компьютере Microsoft Office (или Open Office). Это на самом деле так (это второй вопрос)?

    В отчёт необходимо включать графики. До этого (когда я работал с FixedDocument), я внедрял их следующим образом:

    ExpandedWrap disabled
      // ...
       
      FixedDocument report = new FixedDocument();
      ReportViewer.Document = report;                // ReportViewer - это экземпляр DocumentViewer
       
      PageContent pageContent = new PageContent();
      FixedPage fixedPage = new FixedPage();
       
      // Панель вывода
      StackPanel pageOne = new StackPanel();
      pageOne.Margin = new Thickness(25);
       
      // ...
       
      // График
      Chart pChart = new Chart();
      BarSeries pSeries = new BarSeries();
      pSeries.IndependentValueBinding = new Binding("Key");
      pSeries.DependentValueBinding = new Binding("Value");
      pChart.Series.Add(pSeries);
      List<ISShop> pShop = imWindow.Threads.Statistic.Shops;
      KeyValuePair<String, Double>[] pData = new KeyValuePair<String, Double>[pShop.Count];
      pSeries.ItemsSource = pData;
      pChart.Title = ISShop.CustomerCount;
      for (Int32 i = 0; i < pShop.Count; i++)
      {
          pData[i] = new KeyValuePair<string, double>(imWindow.mainWindow.Data.sale[i].BuildingTitle, pShop[i].dic[ISShop.CustomerCount].Average);
      }
      pSeries.LegendItems.Clear();
      pChart.MinWidth = 770;
      pChart.MinHeight = 400;
      pageOne.Children.Add(pChart);
       
      // ...
      fixedPage.Children.Add(pageOne);
      ((IAddChild)pageContent).AddChild(fixedPage);
      report.Pages.Add(pageContent);


    Для построения графиков, мы используем WPF Toolkit (я так понимаю, что он тоже бесплатный? – это вопрос №3).

    В библиотеке ExportToRTF есть функция
    ExpandedWrap disabled
      PutImage(string PathToJpegFile);

    которая, как Вы уже наверное догадались, вставляет в документ картинку формата JPG, сохранённую в указанном файле.

    Следовательно, для того, чтобы вставить график, я должен получить скриншот контрола Chart из WPF Toolkit с построенным графиком, затем сохранить его в JPG файл (во временную директорию) и далее воспользоваться функцией PutImage.

    Вопрос №4: Как получить скриншот компонента Chart?

    Ранее, для того, чтобы получить скриншот компонента WPF, я использовал следующий алгоритм (я его привёл для рассматриваемого случая):

    ExpandedWrap disabled
      // ...
      Chart chart;
      // ...
      RenderTargetBitmap rtbChart = new RenderTargetBitmap((int)chart.Width, (int)chart.Height, 96, 96, PixelFormats.Default);
      rtbChart.Render(chart);
      BitmapEncoder ChartImage = new JpegBitmapEncoder();
      ChartImage.Frames.Add(BitmapFrame.Create(rtbChart));
      FileStream st = new FileStream(@"D:\1.jpg", FileMode.Create);
      ChartImage.Save(st);
      st.Close();


    Однако в данном случае (см. выше), вместо контрола Chart, на скриншоте только чёрный прямоугольник.

    В принципе, я догадываюсь, почему так происходит. Скорее всего, это из-за того, что сам Chart, я не размещаю в окне. Я создаю его в программе и затем пытаюсь взять с него скриншот. Если Chart находится в окне и я пытаюсь его (или всё окно) отрендерить – то всё проходит нормально, на скриншоте – нужный мне график.

    Последний вопрос (он дублирует предыдущий): каким образом я могу сохранить изображение графика (компонент Chart из WPF Toolkit) в файл?

    Я понимаю, что могут быть "костыли" (создать окно с одним только графиком, подождать пока он построится, взять с него скриншот показанным выше методом, и закрыть его), но, хотелось бы сразу всё сделать правильно.

    Заранее выражаю огромную благодарность каждому откликнувшемуся.
      RTF, конечно, может и круто, но, ИМХО, OpenXML сейчас самое то, на что следует обратить внимание.

      Цитата Amokk @
      каким образом я могу сохранить изображение графика (компонент Chart из WPF Toolkit) в файл?

      Посмотрите тут.

      Добавлено
      Цитата Amokk @
      насколько я понял, она не требует установленного на компьютере Microsoft Office (или Open Office). Это на самом деле так (это второй вопрос)?

      RTF и правда не зависит от установленного пакета Офиса, да и открывается даже WordPad'ом, правда с соответствующим функционалом.
        Цитата Spawn.NET @
        Посмотрите тут


        Хм, а чем этот код отличается от того, который я привёл выше (который в данном случае, когда Chart не отображён в окне, не работает)?
          ответ на вопрос 4 и 5

          ExpandedWrap disabled
            public string SelfScreen()
                    {
                        var renderTargetBitmap = new RenderTargetBitmap(
                            (int)SystemParameters.FullPrimaryScreenWidth,
                            (int)SystemParameters.FullPrimaryScreenHeight,
                            96, 96, PixelFormats.Pbgra32);
                        renderTargetBitmap.Render(this); //в this кладешь Visual объекта который отскринить надо
                        // Сохранение. Вместо renderTargetBitmap можно передать любой BitmapSource
                        var jpegBitmapEncoder = new JpegBitmapEncoder {QualityLevel = 100};
                        jpegBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
                        var fileName = string.Format(@"{0}\Screenshot.jpg", Path.GetTempPath());
                        if (File.Exists(fileName))
                            File.Delete(fileName);
                        var fileStream = new FileStream(fileName, FileMode.CreateNew);
                        jpegBitmapEncoder.Save(fileStream);
                        fileStream.Close();
                        return fileName;
                    }


          таким макаром у меня WPF окно само себя скринит

          а вот по поводу экспорта в Word я ничего не могу сказать потому как помучившись я все таки решил что FlowDocument и XPS круто и удобно. Вот кстати можешь посмотреть нашу реализацию, это блог моего шефа, от периодически кидает туда что то из наших экспериментов, механизм естественно только поверхностно описан, но проявив некую смекалку можно допилить :)

          Добавлено
          Цитата Spawn.NET @
          RTF, конечно, может и круто, но, ИМХО, OpenXML сейчас самое то, на что следует обратить внимание.

          согласен на все сто, все Excel'евские отчеты делаем через OpenXML, основной полюс это то что работает и с OO и с Excel, причем не требует их установленными, да и свой редактор просто намутит. Но есть и минусы, сложно сделать хитрые шаблоны для экспорта, считай для каждого шаблона свой обработчик :(
          Сообщение отредактировано: Pit-Bul -
            Цитата Amokk @
            По окончании эксперимента (моделирования) у нас есть много данных, которые необходимо визуализировать (в виде текста, таблиц, графиков и диаграмм).

            Систему генерации отчетов не хотите попробовать? Тот же StimulSoft умеет сохранять и в RTF, и в DOCX, возможности по составлению и оформлению отчетов богатейшие, рекомендую. Вручную получать скриншоты компонентов - на мой взгляд, вообще занятие неблагодарное.
            Сообщение отредактировано: Raistlin -
              Цитата Raistlin @
              Вручную получать скриншоты компонентов - на мой взгляд, вообще занятие неблагодарное


              а как ты предполагаешь это в том же стимуле сделано ??? Я понимаю конечно если сделать свой контрол для отображения диаграмм, то его легко можно попросить выплюнуть это дело в битмап !О а не умеет ли это делать мелкософтовский Chart, я видел его ранние версии и вроде как там были какие то извращения с BitmapImage если я ничего не путаю
                Цитата Pit-Bul @
                а как ты предполагаешь это в том же стимуле сделано ???

                Без понятия, а стимул как раз и позволяет не думать о таких вещах :)
                Сообщение отредактировано: Raistlin -
                  Кстати, а при помощи OpenXML можно создавать WORD'овские графики и диаграммы? Насколько сложно это будет?
                    Со Smart-Art'ом проблем точно не будет, а вот диаграммы, портируемые из Excel'я хранятся в крайне кривом виде, представляют из себя картинку в String Base64, ну и данные для её формирования, как я понял.
                      Amokk, а в чем проблема, если уж ты все собираешься выгружать в Word, так сделай пару методов которые по массиву данных в битмап отрисовывают график, не такая уж это сложная весчь, да и примеров рисования всяких диаграмм и графиков на том же кодепроджекте полно
                        Цитата Pit-Bul @
                        Amokk, а в чем проблема, если уж ты все собираешься выгружать в Word, так сделай пару методов которые по массиву данных в битмап отрисовывают график, не такая уж это сложная весчь, да и примеров рисования всяких диаграмм и графиков на том же кодепроджекте полно

                        В Word красивее :) В также ещё зависит от того, надо ли иметь доступ к характеристикам графика из самого документа, или даже редактировать его в самом документе
                          Цитата Spawn.NET @
                          надо ли иметь доступ к характеристикам графика из самого документа, или даже редактировать его в самом документе

                          ну вот это я считаю уже перебором, поясню свою позицию :

                          а. Человеку нужно сделать отчет. Отчет - это снимок состояния набора данных в определенный момент времени (во как извратился :) )
                          б. Судя по тому что есть данные которые пойдут в отчет, значит есть программа которая работает с этими данными, а соответственно должна давать возможность манипулировать этими данными.

                          так вот объяснитеж мне какого лешего скрещивать эти две абсолютно разные функции, какого лешего давать пользователю редактировать отчет после того как он сформирован из рабочих данных, если отчет не верный то соответственно неверны входные данные, в этом случае надо поправить входные данные и сформировать новый отчет.
                            Pit-Bul, я просто предполагаю :) Что такое отчёт я знаю, но также я знаю, что от меня не так давно помощник министра потребовал чтобы примерно такой же отчёт был в формате Excel, чтобы можно было вносить изменения...
                            Сколько не выпендривался, сказано - сделано :)
                              Pit-Bul, Вы невнимательно прочитали проблему. Ваш код (как и мой) не работают, т.к. создаваемый контрол Chart (из WPF Toolkit) НЕ ВЫВОДИТСЯ НА ОКНО. Он создаётся в коде, в нём строится график и нужно получить его скриншот (но при этом сам Chart на экране не отображать)!
                                ну тогда тем более не вижу смысла с Chart заморачиваться, а еще раз прочитать это

                                Цитата Pit-Bul @
                                Amokk, а в чем проблема, если уж ты все собираешься выгружать в Word, так сделай пару методов которые по массиву данных в битмап отрисовывают график, не такая уж это сложная весчь, да и примеров рисования всяких диаграмм и графиков на том же кодепроджекте полно


                                Добавлено
                                Amokk, и давай без вы, а то как то совестно даже :)
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1353 ]   [ 16 queries used ]   [ Generated: 8.12.25, 09:19 GMT ]