Змінюй хід війни! Допомагай ЗСУ!

C#. Построение и сохранение таблиц

🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
Статус: Offline
Реєстрація: 14.09.2005
Повідом.: 952
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #1
C#. Построение и сохранение таблиц

Здравствуйте. Встала такая задача: необходимо создавать таблицу, с заголовками столбцов и строк. Количество строк и столбцов варьируется, так же как и размер заголовка. После того, как получена таблица, её необходимо сохранять в файл.
У меня было несколько вариантов решения:
1. Построение таблицы в текстовом виде. Я не нашёл вообще никаких описаний, по какому принципу строятся такие таблицы, а именно, как рассчитываются размеры ячеек в зависимости от заголовков и содержимого ячеек и как потом туда заносить данные.
2. Построение таблицы при помощи контрола tableLayoutPanel. Таблицу тут построить не проблема, но вот сохранить как следует не получается. Для сохранения нашёл только метод DrawToBitmap(). С его помощью таблица сохраняется как изображение, но при этом почему-то некоторые участки не прорисовываются (см. прикрепленное изображение)
3. Построение таблицы с помощью DataGridView. Тут тоже в принципе можно построить таблицу и все размеры можно автоматически подогнать. Сохраняется в изображение тоже нормально, но вот только не понятно, как сделать, чтобы сохранялась только таблица, а не вся область DataGridView.

Есть какие-нибудь идеи по поводу описанного мной или как-то по другому?
 

Вкладення

  • Таблица.png
    Таблица.png
    21.9 КБ · Перегляди: 1123
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #2
погодь, в каком виде тебе нужна таблица? в виде изображения?
почему бы не строить(рисовать) сразу в System.Drawing.Bitmap?
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #3
Здравствуйте. Встала такая задача: необходимо создавать таблицу, с заголовками столбцов и строк. Количество строк и столбцов варьируется, так же как и размер заголовка. После того, как получена таблица, её необходимо сохранять в файл.
да, собственно файл этот для чего нужен?
позырить ради или надо потом загружать из него данные?
или ваще нужен экспорт в картинке?
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #4
погодь, в каком виде тебе нужна таблица? в виде изображения?
почему бы не строить(рисовать) сразу в System.Drawing.Bitmap?
Таблица нужна в нормальном виде и должна быть возможность получать из него изображение.. Если пробовать рисовать таблицу руками, то это будет кошмар.

да, собственно файл этот для чего нужен?
позырить ради или надо потом загружать из него данные?
или ваще нужен экспорт в картинке?
Сохранение таблицы в файл необходимо для того, чтобы хранить результаты и при необходимости эту таблицу засунуть в документ и отправить на печать...
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #5
тогда не заморачивайся с изображениями, а сделай следующее:
1. отображай таблицу во что тебе удобно (DataGrid, ListView, ...)
2. когда встанет вопрос об отправке на печать, сгенерь какой-нибудь промежуточный HTML (с TABLE'ами, TR'ами, TD'шками и пр.) и отправь на печать его.

и проще и дешевле
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #6
тогда не заморачивайся с изображениями, а сделай следующее:
1. отображай таблицу во что тебе удобно (DataGrid, ListView, ...)
2. когда встанет вопрос об отправке на печать, сгенерь какой-нибудь промежуточный HTML (с TABLE'ами, TR'ами, TD'шками и пр.) и отправь на печать его.

и проще и дешевле
+1 за экспорт в HTML.
сам так делаю там де таблицу надо "задокументировать".
и пофиг чем оно отбражается, ListView или еще чем..
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #7
HTML это, конечно, интересно, но изображение предпочтительнее, потому что, как я уже сказал, таблицы будут печататься не отдельно. Это будет скорее всего вордовский документ, отчёт, в который и нужно вставлять изображения..

Нашёл в чём проблема во время прорисовки графика из tableLayoutPanel. Как всегда и бывает, решение проблемы оказалось до отупения гениальным: такие глюки с прорисовкой из-за того, что по-умолчанию фон у таблицы стоит прозрачный. При изменении на любой нормальный цвет всё прорисовывается как надо... Всем спасибо за помощь!
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #8
3. Построение таблицы с помощью DataGridView. Тут тоже в принципе можно построить таблицу и все размеры можно автоматически подогнать. Сохраняется в изображение тоже нормально, но вот только не понятно, как сделать, чтобы сохранялась только таблица, а не вся область DataGridView.
нужно написать свой алгоритм, в котором и описать процесс выборки каких строк и столбцов тебе нужно, а не всё подряд
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #9
HTML это, конечно, интересно, но изображение предпочтительнее

а HTML на битмапку отрендерить и сохранить ее в нужном формате (jpg/gif/bmp/png и т.д.) религия не позволяет?

Если пользуешь первый фреймворк то в нем нет WebBrowser'а, его нужно импортить вручную. Начиная со второй версии компонент WebBrowser присутствует. Добавляешь обработчик OnDocumentComplete:
Код:
[Guid("3050f669-98b5-11cf-bb82-00aa00bdce0b"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
    ComVisible(true),
    ComImport]
interface IHTMLElementRender
{
    void DrawToDC([In] IntPtr hDC);
    void SetDocumentPrinter([In, MarshalAs(UnmanagedType.BStr)] string bstrPrinterName, [In] IntPtr hDC);
};

private void OnDocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
    IHTMLDocument2 document = (IHTMLDocument2) this.axWebBrowser1.Document;
    if (document != null)
    {
          IHTMLElement element = (IHTMLElement) document.body;
          if (element != null)
          {
              IHTMLElementRender render = (IHTMLElementRender) element;
              if (render != null)
              {
                    using(Bitmap bmp = new Bitmap(1024,768))
                    using (Graphics g = Graphics.FromImage(bmp))
                    {
                          render.DrawToDC(g.GetHdc());
                          bmp.Save("MyTableImage.bmp");
                    }
              }
          }
    }
}

код скомпоновал, не тестил, но думаю смысл понятен, должно работать ;)
 
Останнє редагування:
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #10
нужно написать свой алгоритм, в котором и описать процесс выборки каких строк и столбцов тебе нужно, а не всё подряд
Я уже реализовал построение и сохранение таблиц через объект TableLayoutPanel
Через DataGridView знаю только использование метода DataGridView.DrawToBitmap(). Таблицу как раз и нужно сохранять целиком, но вот как делать выборку или сохранять отдельные наборы столбцов или строк - я не знаю

а HTML на битмапку отрендерить и сохранить ее в нужном формате (jpg/gif/bmp/png и т.д.) религия не позволяет?
Опять таки, через TableLayoutPanel.DrawToBitmap() рендерит таблицу нормально и вызовом одной функции
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #11
Опять таки, через TableLayoutPanel.DrawToBitmap() рендерит таблицу нормально и вызовом одной функции

да нахрен тебе та таблица сдалась? :confused: Тебе чтото в ней поменять надо будет и опять голову ломать будешь, вместо того чтобы в html пару тегов добавить
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #12
да нахрен тебе та таблица сдалась? Тебе чтото в ней поменять надо будет и опять голову ломать будешь, вместо того чтобы в html пару тегов добавить
Не понял, что поменять, например? Таблица просто выводит набор полей из базы данных плюс при необходимости она сортируется и выводится процентные соотношения..
Чтобы изменить количество строк или столбцов достаточно изменить их число в соответствующем свойстве объекта. Добавление объекта в таблицу - .Add(объект, столбец, строка). Где тут ломать голову?
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #13
Не понял, что поменять, например? Таблица просто выводит набор полей из базы данных плюс при необходимости она сортируется и выводится процентные соотношения..
Чтобы изменить количество строк или столбцов достаточно изменить их число в соответствующем свойстве объекта.

вот и подумай что будет проще поменять - таблицу в html'е или какойто уродливый объект. Впрочем делай как знаешь, пока человек на грабли не наступит так и не научится ничему :)
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #14
вот и подумай что будет проще поменять - таблицу в html'е или какойто уродливый объект
Конечно, объект.
В объекте:
Код:
tableLayoutPanel1.ColumnCount = NewColumnCount;
tableLayoutPanel1.RowCount = NewRowCount;

В html же это выглядит как добавление массы тэгов. Вообще html подразумевает разметку, нужно соответственно помимо всего прочего ещё думать о том, чтобы везде текст влазил. А в случае с tableLayoutPanel, размеры таблицы подгоняются автоматически.

Впрочем делай как знаешь, пока человек на грабли не наступит так и не научится ничему
Ну и где тут грабли? Или тут скорее "граблей бояться - в сарай не ходить"? Не вижу проблемы - уже почти как неделю всё сделано и работает и никаких проблем..

P.S. И, наконец, у меня есть таблица, которая строится прямо на форме. Пользователь на неё смотрит и если нужно - сохраняет. Так вот, нужно чтобы она выглядела точно так же как она построена и при сохранении из объекта это будет то же, что видит пользователь.. html будет выглядеть по-другому.
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #15
html - hyper text
он тоже свободно тянется, в зависимости от контента. Klez дело говорит.
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #16
Конечно, объект.
В объекте:
Код:
tableLayoutPanel1.ColumnCount = NewColumnCount;
tableLayoutPanel1.RowCount = NewRowCount;
В html же это выглядит как добавление массы тэгов.

дуракам закон не писан :D

html генерить нужно не тупым плюсованием тегов, а с умом - из DataSet'а. Например, я бы сделал так - кидаешь данные в DataSet, сохраняешь в XML, трансформируешь с помощью XSL в HTML. Грузишь в WebBrowser, из обработчика OnDocumentComplete рендеришь содержимое в битмапку и сохраняешь битмапку как bmp или jpeg на диск ;)

Пользователю показывать можешь тот-же WebBrowser загрузив в него сгенеренный HTML. Все будет выглядеть один в один, т.к. будет использован один и тот-же рендерер... ;)

Если надо подправить внешний вид - достаточно XSLT файло с шаблоном поправить. Никаких свойств и кривых объектов юзать не надо. Все автоматом рендерится, таблицы авторесайзятся как душе угодно и т.п. Оформление на любой вкус - все возможности HTML/CSS к вашим услугам ;)

Если в дальнейшем появится необходимость сохранять например в PDF, добавляешь еще один XSL скрипт для трансформации в FO и цепляешь nFOP, которым процессишь FO в PDF

и это все - десять-двадцать строк на C#, все остальное - оформление рюшечек на HTML/CSS

P.S. И, наконец, у меня есть таблица, которая строится прямо на форме. ...
html будет выглядеть по-другому.

а нефик "строить таблицы на форме"! Кладешь на форму WebBrowser, загружаешь в него сгенеренный HTML и все будет выглядеть 1 в 1, что в картинке, что на форме, что на принтере... ;)
Более того, пользователь получает возможность копировать часть или всю таблицу в WORD или EXCEL, сохранять ее не только как bmp/jpeg, но и как HTML. И даже более того - в таблице можно будет использовать гиперссылки на другие таблицы и т.п. И для реализации этих возможностей не нужно дописывать ни одной строчки кода! ;)

Ну и где тут грабли? Или тут скорее "граблей бояться - в сарай не ходить"?

лет через 5-10 поймешь ;)
 
Останнє редагування:
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #17
кстати, рендер в битмап тут лишнее. не городите огород.
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #18
кстати, рендер в битмап тут лишнее. не городите огород.

вобщем-то да, я как-то упустил из виду что ТС-у сохранение картинки нужно было чтобы можно было в WORD/EXCEL вставлять. А раз это решается простым копированием. То и необходимость рендера в битмапку отпадает за ненадобностью... :)
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #19
html генерить нужно не тупым плюсованием тегов, а с умом - из DataSet'а. Например, я бы сделал так - кидаешь данные в DataSet, сохраняешь в XML, трансформируешь с помощью XSL в HTML. Грузишь в WebBrowser, из обработчика OnDocumentComplete рендеришь содержимое в битмапку и сохраняешь битмапку как bmp или jpeg на диск

Пользователю показывать можешь тот-же WebBrowser загрузив в него сгенеренный HTML. Все будет выглядеть один в один, т.к. будет использован один и тот-же рендерер...

Если надо подправить внешний вид - достаточно XSLT файло с шаблоном поправить. Никаких свойств и кривых объектов юзать не надо. Все автоматом рендерится, таблицы авторесайзятся как душе угодно и т.п. Оформление на любой вкус - все возможности HTML/CSS к вашим услугам

Если в дальнейшем появится необходимость сохранять например в PDF, добавляешь еще один XSL скрипт для трансформации в FO и цепляешь nFOP, которым процессишь FO в PDF

и это все - десять-двадцать строк на C#, все остальное - оформление рюшечек на HTML/CSS
Нет, я не спорю, может так и правильнее.. Но в первую очередь меня интересует вопрос: почему? Просто объясни. Конечно, можно переделать то, что уже работает, но чтобы начинать работать в этом направлении, необходима какая-то веская причина. Вот чем не устроили свойства и чем кривы эти объекты?

Я просто выбрал наиболее простой и понятный мне, опять таки, найденный мною способ реализовать функцию, чтобы было больше времени на более важный функционал. Метод с HTML кажется мне, как минимум, более сложным. Хотя, может быть, если бы я подробно разобрался что и как работает, моё мнение изменилось бы
 
  • 🟠 21:50 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #20
Нет, я не спорю, может так и правильнее.. Но в первую очередь меня интересует вопрос: почему?

ответ прост, код лучше писать хорошо, чтобы потом не пришлось переделывать, а на случай если бы и пришлось, то чтобы это было просто
 
Назад
Зверху Знизу