我正在尝试在 printpreview 中打印 HTML 中的数据表内容并直接打印,包括标题/设置纸张/方向/适合 VB.NET 中的页面。
也许在rdlc报告中很容易做到,但我无法使用它,因为角色名称属性问题不允许它。
所以我通过转换为html来采取这个解决方案或者还有其他解决方案请给我建议
我有下面的代码,但这仍然是错误的。
还有其他方法请指导吗
谢谢
Private dt As New DataTable
Private Function CreateConnection() As OleDbConnection
Return New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\transposerowtocolumnsqlmsaccessvbnet.accdb;Persist Security Info=False;")
End Function
Private Function LoadData() As DataTable
Dim dt As New DataTable()
Using con = CreateConnection(), cmd = con.CreateCommand(),
ta = New OleDbDataAdapter(cmd)
Dim sql = <sql>
TRANSFORM Sum(Tableproduct.Qty) AS SumOfQty
SELECT Tableproduct.Codeproduct AS CodeProduct, Tableproduct.Colour AS Colour, Sum(Tableproduct.Qty) AS Total
FROM Tableproduct INNER JOIN SizeProduct ON Tableproduct.Size = SizeProduct.Size
WHERE (((Tableproduct.Codeproduct)='B'))
GROUP BY Tableproduct.Codeproduct, Tableproduct.Colour
PIVOT SizeProduct.Size;
</sql>.Value
cmd.CommandText = sql
ta.Fill(dt)
End Using
Return dt
End Function
Private Function ExportDatatableToHtml(ByVal dt As DataTable) As String
Dim stringBuilder As New StringBuilder()
stringBuilder.Append("<html >")
stringBuilder.Append("<head>")
stringBuilder.Append("<meta charset='utf-8'>")
stringBuilder.Append("</head>")
stringBuilder.Append("<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css' integrity='sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk' crossorigin='anonymous'>")
stringBuilder.Append("<script src='https://code.jquery.com/jquery-3.3.1.slim.min.js' integrity='sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo' crossorigin='anonymous'></script>")
stringBuilder.Append("<script src='https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js' integrity='sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy' crossorigin='anonymous'></script>")
stringBuilder.Append("<body>")
stringBuilder.Append("<table class='table table-sm table-hover' style='margin: 20px;'>")
stringBuilder.Append("<thead>")
stringBuilder.Append("<tr class='bg-primary' style='color: white; text-align: left;'>")
For Each column As DataColumn In dt.Columns
stringBuilder.Append("<th class='border border-secondary'>")
stringBuilder.Append(column.ColumnName)
stringBuilder.Append("</th>")
Next column
stringBuilder.Append("</tr>")
stringBuilder.Append("</thead>")
For Each row As DataRow In dt.Rows
stringBuilder.Append("<tr>")
For Each column As DataColumn In dt.Columns
stringBuilder.Append("<td class='border border-secondary'>")
stringBuilder.Append(row(column.ColumnName).ToString())
stringBuilder.Append("</td>")
Next column
stringBuilder.Append("</tr>")
Next row
stringBuilder.Append("</table>")
stringBuilder.Append("</body>")
stringBuilder.Append("</html>")
Dim html = stringBuilder.ToString()
Return html
End Function
Private Sub BRNCONVERT_Click(sender As Object, e As EventArgs) Handles BRNCONVERT.Click
Using saveFileDialog As New SaveFileDialog() With {.Filter = "Html files|*.html"}
If saveFileDialog.ShowDialog() = DialogResult.OK Then
Dim html As String = ExportDatatableToHtml(LoadData())
System.IO.File.WriteAllText(saveFileDialog.FileName, html)
End If
End Using
End Sub
上面代码的结果:
下面包括我要设置的内容:
样本数据:
桌子桌子产品
代码产品 | 颜色 | 尺寸 | 数量 |
---|---|---|---|
A | 白色 | S | 15 |
A | 黑色 | M | 20 |
A | 白色 | L | 10 |
A | - | 20 | |
A | XXL/2L | 15 | |
B | 蓝色 | S | 20 |
A | 白色 | XL | 15 |
桌子尺寸产品
产品尺寸 | 顺序 |
---|---|
- | 1 |
S | 2 |
M | 3 |
L | 4 |
XL | 5 |
XXL/2L | 6 |
想要的结果
对于代码Product = A
SAMPLE
因沃诺:1000
代码产品 | 颜色 | - | S | M | L | XL | 总计 |
---|---|---|---|---|---|---|---|
A | 20 | 10 | 35 | ||||
A | 黑色 | 20 | 20 | ||||
A | 白色 | 15 | 10 | 25 |
Grandtotal : 80
对于代码Product = B
SAMPLE
因沃诺:1000
代码产品 | 颜色 | S | XL | 总计 |
---|---|---|---|---|
B | 蓝色 | 20 | 20 | |
B | 白色 | 15 | 10 |
Grandtotal : 30
交叉表查询
考虑问题中表格的设计。
TableProduct
和 SizeProduct
表之间没有数据库关系。它们有一个重复的字段,并且仅具有该字段并不意味着这两个表是相关的。这意味着查询中的 JOIN
部分根本没有意义。您不需要连接表中的任何内容,因为您已经在 TableProduct
中拥有 pivot 字段。所以,查询应该是这样的:
TRANSFORM Sum(Tableproduct.Qty) AS SumOfQty
SELECT Tableproduct.Codeproduct AS CodeProduct,
Tableproduct.Color AS Color,
Sum(Tableproduct.Qty) AS Total
FROM Tableproduct
WHERE Tableproduct.Codeproduct = 'A'
GROUP BY Tableproduct.Codeproduct, Tableproduct.Color
PIVOT Tableproduct.Size
如果
TableProduct
包含一个 外键 字段,该字段保留 SizeProduct
表中相关的唯一 主键值,那么您的查询就有意义。然后我们可以说两个表之间存在关系,并且您的交叉表查询可能是这样的:
TRANSFORM Sum(Tableproduct.Qty) AS SumOfQty
SELECT Tableproduct.Codeproduct AS CodeProduct,
Tableproduct.Color AS Color,
Sum(Tableproduct.Qty) AS Total
FROM Tableproduct
INNER JOIN SizeProduct ON Tableproduct.SizeId = SizeProduct.Id
WHERE Tableproduct.Codeproduct = 'A'
GROUP BY Tableproduct.Codeproduct, Tableproduct.Color
PIVOT SizeProduct.Size
更多请阅读:
如何定义 Access 数据库中表之间的关系。
数据表到 HTML 表
现在,我们应该有一个方法来运行交叉表查询,填充并返回一个
DataTable
,如下所示:
Private Function LoadData(code As String) As DataTable
Dim dt As New DataTable()
Dim sql = <sql>
TRANSFORM Sum(Tableproduct.Qty) AS SumOfQty
SELECT Tableproduct.Codeproduct AS CodeProduct,
Tableproduct.Color AS Color,
Sum(Tableproduct.Qty) AS Total
FROM Tableproduct
WHERE Tableproduct.Codeproduct = '<%= code %>'
GROUP BY Tableproduct.Codeproduct, Tableproduct.Color
PIVOT Tableproduct.Size</sql>.Value
Using con = CreateConnection(),
cmd = New OleDbCommand(sql, con),
ta = New OleDbDataAdapter(cmd)
ta.Fill(dt)
End Using
' Make it the last column.
dt.Columns("Total").SetOrdinal(dt.Columns.Count - 1)
Return dt
End Function
创建 HTML 输出的方法,包括总计值。
Private Function DataTableToHtml(dt As DataTable) As String
Dim Invono = "ABC123"
Dim html =
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<style>
table.tb { border-collapse: collapse; width: 100%; }
.tb th, .tb td { padding: 5px; border: solid 1px; }
.tb th { background-color: lightblue;}</style>
</head>
<body>
<h2 style="margin-bottom: 0.3em">Some Title</h2>
<p>
<b>Invono: </b><%= Invono %><br/>
<b>More Info:</b> Whatever...
</p>
<table class="tb">
<thead>
<tr>
<%= dt.Columns.Cast(Of DataColumn).
Select(Function(col) <th><%= col.ColumnName %></th>) %>
</tr>
</thead>
<tbody>
<%= dt.AsEnumerable().Select(
Function(row)
Return _
<tr>
<%=
row.ItemArray.OfType(Of Object).Select(
Function(cell) <td><%= cell.ToString() %></td>)
%>
</tr>
End Function) %>
<tr>
<td style="border: 0px; text-align: right;" colspan=<%= dt.Columns.Count - 1 %>><strong>Grand Total</strong></td>
<td><strong><%= dt.Compute("SUM(Total)", Nothing) %></strong></td>
</tr>
</tbody>
</table>
</body>
</html>
Return html.ToString()
End Function
像这样实现:
Private Sub SomeButton_Click(sender As Object, e As EventArgs) Handles SomeButton.Click
Dim htmlFile = "..."
Using dt = LoadData("A")
File.WriteAllText(htmlFile, DataTableToHtml(dt))
End Using
End Sub
您没有显示打印部分。但是,无论您在打印对话框中指定哪种页面大小、边距和方向,此处的 html 表格都将填充页面边界的宽度。