Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/25: Рейтинг темы: голосов - 25, средняя оценка - 4.88
6 / 5 / 1
Регистрация: 02.05.2015
Сообщений: 182
1

PrintDocument, PrintPreviewDialog - вывод содержимого формы на печать

05.04.2018, 16:53. Показов 4746. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте.
Нашёл код вывода DataGridView на печать, но не могу полностью разобраться. Прошу помощи.
На форме DataGridView1,PrintDocument1, PrintPreviewDialog1.
DataGridView1 такой структуры:
PrintDocument, PrintPreviewDialog - вывод содержимого формы на печать

Код формы:
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
Public Class Form1
    Private Structure pageDetails
        Dim columns As Integer
        Dim rows As Integer
        Dim startCol As Integer
        Dim startRow As Integer
    End Structure
    ''' <summary>
    ''' dictionary to hold printed page details, with index key
    ''' </summary>
    ''' <remarks></remarks>
    Private pages As Dictionary(Of Integer, pageDetails)
 
    Dim maxPagesWide As Integer
    Dim maxPagesTall As Integer
 
    Dim mRow As Integer = 0
    Dim newpage As Boolean = True
 
    Dim s As String
    Const cs As String = " / "
 
 
    Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
 
        PrintDocument1.OriginAtMargins = True
        PrintDocument1.DefaultPageSettings.Margins = New Drawing.Printing.Margins(0, 0, 0, 0)
        '================================
        PrintDocument1.DefaultPageSettings.Landscape = True 'книжная ориентация страницы
        '================================
        pages = New Dictionary(Of Integer, pageDetails)
 
        Dim maxWidth As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width) - 40
        Dim maxHeight As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Height) - 40
 
        Dim pageCounter As Integer = 0
        pages.Add(pageCounter, New pageDetails)
 
        Dim columnCounter As Integer = 0
 
        Dim columnSum As Integer = DataGridView1.RowHeadersWidth
 
        For c As Integer = 0 To DataGridView1.Columns.Count - 1
            If columnSum + DataGridView1.Columns(c).Width < maxWidth Then
                columnSum += DataGridView1.Columns(c).Width
                columnCounter += 1
            Else
                pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
                columnSum = DataGridView1.RowHeadersWidth + DataGridView1.Columns(c).Width
                columnCounter = 1
                pageCounter += 1
                pages.Add(pageCounter, New pageDetails With {.startCol = c})
            End If
            If c = DataGridView1.Columns.Count - 1 Then
                If pages(pageCounter).columns = 0 Then
                    pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
                End If
            End If
        Next
 
        maxPagesWide = pages.Keys.Max + 1
 
        pageCounter = 0
 
        Dim rowCounter As Integer = 0
 
        Dim rowSum As Integer = DataGridView1.ColumnHeadersHeight
 
        For r As Integer = 0 To DataGridView1.Rows.Count - 2
            If rowSum + DataGridView1.Rows(r).Height < maxHeight Then
                rowSum += DataGridView1.Rows(r).Height
                rowCounter += 1
            Else
                pages(pageCounter) = New pageDetails With {.columns = pages(pageCounter).columns, .rows = rowCounter, .startCol = pages(pageCounter).startCol, .startRow = pages(pageCounter).startRow}
                For x As Integer = 1 To maxPagesWide - 1
                    pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter).startRow}
                Next
 
                pageCounter += maxPagesWide
                For x As Integer = 0 To maxPagesWide - 1
                    pages.Add(pageCounter + x, New pageDetails With {.columns = pages(x).columns, .rows = 0, .startCol = pages(x).startCol, .startRow = r})
                Next
 
                rowSum = DataGridView1.ColumnHeadersHeight + DataGridView1.Rows(r).Height
                rowCounter = 1
            End If
            If r = DataGridView1.Rows.Count - 2 Then
                For x As Integer = 0 To maxPagesWide - 1
                    If pages(pageCounter + x).rows = 0 Then
                        pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter + x).startRow}
                    End If
                Next
            End If
        Next
 
        maxPagesTall = pages.Count \ maxPagesWide
 
    End Sub
 
 
    Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
 
        Dim rect As New Rectangle(20, 130, CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width), 20)
        Dim sf As New StringFormat(StringFormatFlags.LineLimit)
        sf.Alignment = StringAlignment.Center
        sf.LineAlignment = StringAlignment.Center
 
 
        Dim startX As Integer = 50
        Dim startY As Integer = rect.Bottom
        Static startPage As Integer = 0
 
        For p As Integer = startPage To pages.Count - 1
            Dim cell As New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.ColumnHeadersHeight)
            e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
            e.Graphics.DrawRectangle(Pens.Black, cell)
 
            startY += DataGridView1.ColumnHeadersHeight
 
            For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
                cell = New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.Rows(r).Height)
                e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
                e.Graphics.DrawRectangle(Pens.Black, cell)
                e.Graphics.DrawString(DataGridView1.Rows(r).HeaderCell.FormattedValue.ToString, DataGridView1.Font, Brushes.Black, cell, sf)
                startY += DataGridView1.Rows(r).Height
            Next
 
            startX += cell.Width
            startY = rect.Bottom
 
            For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
                cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.ColumnHeadersHeight)
                e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
                e.Graphics.DrawRectangle(Pens.Black, cell)
                e.Graphics.DrawString(DataGridView1.Columns(c).HeaderCell.Value.ToString, DataGridView1.Font, Brushes.Black, cell, sf)
                startX += DataGridView1.Columns(c).Width
            Next
 
            startY = rect.Bottom + DataGridView1.ColumnHeadersHeight
 
            For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
                startX = 50 + DataGridView1.RowHeadersWidth
                For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
                    cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.Rows(r).Height)
                    e.Graphics.DrawRectangle(Pens.Black, cell)
                    e.Graphics.DrawString(DataGridView1(c, r).FormattedValue.ToString, DataGridView1.Font, Brushes.Black, cell, sf)
                    startX += DataGridView1.Columns(c).Width
                Next
                startY += DataGridView1.Rows(r).Height
            Next
 
            If p <> pages.Count - 1 Then
                startPage = p + 1
                e.HasMorePages = True
                Return
            Else
                startPage = 0
            End If
 
        Next
 
    End Sub
 
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Dim ppd As New PrintPreviewDialog
        ppd.Document = PrintDocument1
        ppd.WindowState = FormWindowState.Maximized
        ppd.ShowDialog()
    End Sub
End Class
При выводе на печать, в пред.просмотре,получается подобная таблица:
PrintDocument, PrintPreviewDialog - вывод содержимого формы на печать


а необходимо получить такую таблицу:
PrintDocument, PrintPreviewDialog - вывод содержимого формы на печать

то есть, что бы таблица помещалась на одной странице, что бы не было столбика перед столбиком "№", и что бы текст в первом столбике выравнивался по левому краю. Так же, очень желательно, что бы содержимое ячейки таблицы, при необходимости, переносилось на новую строку, по типу multiline.

Буду весьма признателен за Вашу помощь и было бы отлично если бы кто-нибудь смог подробно закоментировать код.

(код не мой, на форме были ещё и другие контролы которые я поудалял, возможно в коде где-нибудь они могут встречаться, хотя ошибок нет)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.04.2018, 16:53
Ответы с готовыми решениями:

Вывод содержимого из Listbox в PrintPreviewDialog
вывод содержимого из Listbox в PrintWievDialog

Вывод содержимого формы на печать - иврит
Добрый день! ТЗ простое: есть форма с текстбоксами, датой, чекбоксами, выпадающими списками и т.д....

Не проходит печать из PrintPreviewDialog
Всем привет. Столкнулся с проблемой: Необходимо вывести на печать DataGridView, но беда в том, что...

Печать всего содержимого формы
У меня есть Windows Forms, и мне нужно, чтобы она печатала содержимое показанное на картинке после...

7
4665 / 3620 / 856
Регистрация: 02.02.2013
Сообщений: 3,490
Записей в блоге: 2
05.04.2018, 19:04 2
Ситуация на картинке говорит о том, что таблица по ширине не умещается в отведенную ей область на листе и последняя колонка переносится на следующий лист. Используйте PageSetupDialog для настройки параметров листа.
Для примера можно посмотреть https://www.cyberforum.ru/post10032653.html
Но можно и по-другому как показано в привязанном архиве.
Вложения
Тип файла: rar fromDGV.rar (20.0 Кб, 72 просмотров)
1
6 / 5 / 1
Регистрация: 02.05.2015
Сообщений: 182
05.04.2018, 19:45  [ТС] 3
Пример в исходниках при попытке запуска выдал 52 ошибки, пример во вложении выдал 15 ошибок.
Ошибки в основном такого типа:
Ошибка 2 "ISupportInitialize" в пространстве имен "System.ComponentModel" является неоднозначным. ***\Downloads\fromDGV\fromDGV\fromDGV\Form1.Designer.vb 33 33 fromDGV
Ну и естественно не запускается.
Из-за чего это может быть?

Ситуация на картинке говорит о том, что таблица по ширине не умещается в отведенную ей область на листе и последняя колонка переносится на следующий лист. Используйте PageSetupDialog для настройки параметров листа.
Это я понял, вот и хотел узнать где именно в коде это ограничение на размер печатного поля. Код изначально использовал книжный лист, мне может понадобиться как книжная ориентация листа , так и альбомная. В коде я задал ориентацию альбомную
VB.NET
1
PrintDocument1.DefaultPageSettings.Landscape = True
но на печать выводится лист по параметрам книжной ориентации.

Добавлено через 27 минут
Сервис - параметры - конструктор windows forms - создание оптимизированного кода = false
не помогает
0
4665 / 3620 / 856
Регистрация: 02.02.2013
Сообщений: 3,490
Записей в блоге: 2
05.04.2018, 20:40 4
Все файлы рабочие. Пример вывода на картинке. Среда VS2010, Net 4.0, разделитель ".". Для Word д.б. установлена ссылка на Microsoft.Office.Interop.Word. Для DGVprint посмотрите сами, какие библиотеки запрашиваются.
Миниатюры
PrintDocument, PrintPreviewDialog - вывод содержимого формы на печать  
0
6 / 5 / 1
Регистрация: 02.05.2015
Сообщений: 182
05.04.2018, 20:57  [ТС] 5
студия 2008
PrintDocument, PrintPreviewDialog - вывод содержимого формы на печать
0
4665 / 3620 / 856
Регистрация: 02.02.2013
Сообщений: 3,490
Записей в блоге: 2
05.04.2018, 21:38 6
Предлагаю вариант для Net 2.0
Хотя, на мой взгляд, вас больше всего должен интересовать код, который вы без проблем можете перенести в свою среду.
Вложения
Тип файла: rar fromDGV_net2.rar (20.8 Кб, 50 просмотров)
1
1 / 1 / 0
Регистрация: 26.10.2017
Сообщений: 108
12.03.2019, 16:52 7
Цитата Сообщение от ovva Посмотреть сообщение
Все файлы рабочие. Пример вывода на картинке
Уважаемый ovva, если все брать из вашего проекта, то все работает. Не подскажите, как перенести в свой проект, если у меня данные в DGV подгружаются из базы access? Ведь в вашем примере DGV заполняется кодом.
Уже всю голову сломал..
0
4665 / 3620 / 856
Регистрация: 02.02.2013
Сообщений: 3,490
Записей в блоге: 2
12.03.2019, 23:24 8
Цитата Сообщение от zhigalkin_p Посмотреть сообщение
как перенести в свой проект, если у меня данные в DGV подгружаются из базы access?
Не очень понял, о каком проекте речь. Буду считать, что о последнем.
Кликните здесь для просмотра всего текста
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Imports WRD = Microsoft.Office.Interop.Word
Imports System.IO
Imports System.Data.OleDb
'Net 4.0
Public Class Form1
    Private withoutC0, withoutRN, allDGV As Boolean
    Private dbPath As String
    Private tb As DataTable
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        dbPath = Path.Combine(Application.StartupPath, "dbBooks.mdb")
        loadTable(dbPath)
        With DataGridView1
            .DataSource = tb
            .ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
        End With
        withoutC0 = CheckBox2.Checked
        withoutRN = CheckBox3.Checked
        allDGV = CheckBox1.Checked
        Me.Location = New Point(50, 50)
    End Sub
    Private Sub loadTable(ByVal dbPath As String)
        Dim connString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbPath & ";Password=;"
        Dim conn As New OleDbConnection(connString)
        tb = New DataTable
        Try
            conn.Open()
            Dim query As String = "SELECT * FROM Books"
            Dim da As OleDbDataAdapter = New OleDbDataAdapter(query, conn)
            da.Fill(tb)
        Catch ex As Exception
            MsgBox(ex.ToString)
        Finally
            conn.Close()
        End Try
    End Sub
'…
End Class
 
Public Class Form3
    Public wCol() As Integer
    Private rtb1 As extRTB
    Private Sub Form3_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim dd(,) = CType(Me.Tag, String(,))
        rtb1 = New extRTB
        With rtb1
            .ZoomFactor = 1
            .Location = New Point(10, 10)
            .Width = 600 : rtb1.Height = 400
            Me.Controls.Add(rtb1)
            .BringToFront()
            .Modified = False
            .ResetText()
            .AppendText("Пример вывода таблицы" & vbCrLf)
            .Rtf = addTableToRtf(dd, wCol, rtb1.Rtf, rtb1.Font)
        End With
    End Sub
'…
End Class
 
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Public Class extRTB
    Inherits RichTextBox
    <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
    Private Shared Function LoadLibrary(dllName As String) As IntPtr
    End Function
    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim baseParams As CreateParams = MyBase.CreateParams
            If LoadLibrary("msftedit.dll") <> IntPtr.Zero Then
                baseParams.ClassName = "RICHEDIT50W"
            End If
            Return baseParams
        End Get
    End Property
End Class

Изменения:
• Заменил штатный RichTextBox на extRTB чтобы таблица не разрушалась в случае многострочных данных в ячейках.
• От Net 2.0 пришлось отказаться т.к. сбивалась кодировка при копировании.
PS. Код только в измененной части, полагаю что вы сможете сложить все вместе.
0
12.03.2019, 23:24
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.03.2019, 23:24
Помогаю со студенческими работами здесь

Печать содержимого формы на принтере
У меня есть форма куда вводятся данные. Есть кнопка &quot;Печатать&quot;. Мне нужно что бы при нажатии кнопки...

Печать содержимого формы через bmp
Добро всем! :senor: Возникла необходимость распечатать форму, пробую передать координаты: int x =...

Печать DataGridView с помощью PrintDocument
День добрый, есть DataGridView который нужно распечатать, мои попытки привели к печати всего окна....

Кнопка для вывода на печать содержимого формы
имеется кнопки &quot;Batton...&quot; на форме, текст в &quot;memo&quot; и в &quot;label&quot; и картинки &quot;Imege&quot;. создаю...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru