栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

生成DocX表格的方法

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

生成DocX表格的方法

编程应用中经常要报表。
本文摘自vs2015、netframework4.61、vb.net源代码,代码本身均不依赖于word环境。

方法一:使用DocX

我需要生成这样的表,下图是mb_MC.docx:

''''安装并引用包,.Net FrameWork 4.0 ,Docx.dll
''install-package docx -version 1.3.0 
Imports Xceed.Words.NET

Sub do_Docx()
	Dim dx As DocX = DocX.Load("mb_MC.docx")
	Dim t = dx.Tables(0)
	Dim r0 = t.Rows(1)'备份第二行,含格式
	
	Dim nr =8, nc =6
	Dim ir, ic As Integer
	For ir = 0 To nr
	    Dim r1 As Row = t.InsertRow(r0, ir + 2) '相当于复制第二行,后面均对新行处理
	    
	    For ic = 0 To nc - 1 '填文本
	        Dim tx ="字段值" '数据来源DataTable的行,...
	        Dim p0 = r1.Cells(ic).Paragraphs(0).Append(tx) '如果格内有其它内容,可以改为替换
	        'p0的格式设置...
	    Next
	    
        Dim p = r1.Cells(nc).Paragraphs(0) '最后列添加图片
        Dim f1 = "you关联图片.jpg"
        If File.Exists(f1) Then
            Dim img As Image = dx.AddImage(f1)
            Dim pic = p.AppendPicture(img.CreatePicture(44, 33)) '填图片,设置高、宽
        Else
            p.Append("没照片")
        End If	    
	Next
	t.RemoveRow(1)
	dx.SaveAs("f.docx")
End Sub

感谢作者:https://github.com/xceedsoftware/docx

方法二:使用TemplateEngine.Docx

模板的创建mb_MC_T.docx(用到了内容控件和图片控件,需要重复的行由内容控件T1包裹):

'Install-Package TemplateEngine.Docx -Version 1.1.4   '.net46+
Imports TemplateEngine.Docx

Sub do_DocxT(dt as DataTable,fDx as Sring)
	File.Copy("mb_MC_T.docx", fDx, True)   '要Try	
	
	Dim TC = New TableContent("T1")		'创建表行重复
	For Each dr As DataRow In dt.Rows
	    Dim ar1 = New List(Of IContentItem)() '文档一行,含FieldContent和ImageContent
	    
	    ''内容字段
        For Each c as DataColumn in dt.Columns
            dim k = c.ColumnName
            dim v = dr(k).ToString() 
            ar1.Add(new FieldContent(k, v))
        Next
	
	    ''添加照片,在模板中为 图片控件
	    Dim f1 = "you关联图片.jpg"
	    Dim bb As Byte()=If(File.Exists(f1),File.ReadAllBytes(f1),New Byte() {}) '读wu.jpg
	    ar1.Add(New ImageContent("pic", bb))
	    ''一行
	    TC.AddRow(ar1.ToArray())
	Next
	
	Dim fillData = New Content(TC, 
								New FieldContent("other", "其它内容值"))	
	
	Using TP As TemplateProcessor = New TemplateProcessor(fDx)
	    TP.SetRemoveContentControls(True).SetNoticeAboutErrors(False)'debug时:True
	    TP.FillContent(fillData)
	    '在此,还有啥要处理:TP.Document.Descendants ... ...
	    TP.SaveChanges()
	End Using
	Process.Start(fDx) 'try
End Sub

有Content、TableContent、FieldContent、ImageContent、RepeatContent、ListContent等等
感谢作者:https://github.com/UNIT6-open/TemplateEngine.Docx

方法三:直接生成rtf吧

用编辑软件做模板,另存为rtf,经写字板(wordpad.exe)打开、保存,精简一下,内容行就是这样子的:

xxxcell xxxcell xxxcell xxxcell xxxcell xxxcell <图片串>cellrow
Private Sub do_Rtf(rr As DataRow(), f0 As String)
    Dim sw As StreamWriter
    Try
        sw = New StreamWriter(f0, False, System.Text.Encoding.Default)  '不追加
    Catch e As Exception
        MsgBox(e.Message, MsgBoxStyle.Critical)
        Exit Sub
    End Try

    Dim rtfH = "{rtf1ansi {fonttbl{f15fnil 宋体}{f16fnil 黑体}}
{colortbl;red0green0blue255;red0green255blue0;red255green255blue0;red255green0blue0;red0green0blue0;}
paperw16840paperh11907margl880margr880margt880margb567gutter0 lndscpsxnviewkind1viewscale100headery600footery567
{header brdrbbrdrsbrdrw5 fs18cf5qj  par}
{footer fs18cf5qr {field{*fldinst {PAGE}}} / {field{*fldinst {NUMPAGES}}} 页 par }".Replace("", f0)

    sw.WriteLine(rtfH)
	
	'列头、列宽,对应
    Dim cc = {"学号", "姓名", "性别", "", "", "",  "照片"}
    Dim cw As Single() = {2.7, 1.7, 1, 2.0, 2.0, 2.0, 1.5} 'cm
    
    sw.WriteLine("fs18trowdtrqctrleft-108trrh400")
	'表格定义
    Dim ww As Integer = 0
    For i As Integer = 0 To cw.Length - 1
        ww += cw(i) * 567
        sw.WriteLine("clvertalcclbrdrtbrdrsclbrdrlbrdrsclbrdrbbrdrsclbrdrrbrdrscltxlrtb cellx" & ww)
    Next
    sw.Write("pard intbl{")'开始 intbl
    '表头行
    sw.Write("qc fs21 {bqc ")
    sw.Write(String.Join("cell ", cc))
    sw.WriteLine("cellrow}")
    '表格内容行,循环
	sw.Write(trrh567")  '行高1CM
    For Each r As DataRow In rr
        '文本列
        ''sw.Write("qc ")        
        For ic = 0 To cc.Length - 2
            sw.Write(r(cc(ic)).ToString() & "cell ")
        Next
        '照片
        Dim ff = "you关联照片.jpg"
        Dim zp = If(File.Exists(ff), rtf_PicStr(ff, 495), "无照片")
        sw.WriteLine($"qc {zp}cellrow")
    Next

    sw.WriteLine("}pard") ''end intbl    
    sw.WriteLine("}")	''end rtf
    
    sw.Flush()
    sw.Close()
End Sub

链接图片文件名就简单了。内嵌的rtf图片串难搞?

Private Function rtf_picStr(fjpg As String, w缇 As Integer) As String
	'1 twips缇的长度等于1/1440英寸;1/567厘米;1/20磅;1英寸=2.54厘米
	If not File.Exists(fjpg) Then Return ""
	
	Dim s = ""
	Dim m = New System.IO.MemoryStream()
	Try
        Dim bp = New System.Drawing.Bitmap(fjpg)
        bp.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg)

		Dim h缇 As Integer = w缇 * bp.Height / bp.Width '保持长宽比
        Dim s1 = $"pictjpegblippicwgoal{w缇}pichgoal{h缇}hex "	
        Dim s2 As String =BitConverter.ToString(m.GetBuffer(), 0).Replace("-", String.Empty)
        bp.Dispose()

        s = "{*shppict{" & s1 & s2 & "}}"
	Catch
	    s = "无"
	Finally
	    m.Close()
	    m.Dispose()
	End Try
	
	Return s
End Function

如果你有空闲时间优化rtf模板,这是运行最快的方法了。

更多的方法:
直接生成xml,类似于rtf;
还可以用openxml SDK生成代码…
值得参考java下poi-tl:http://deepoove.com/poi-tl/

End,vs2015,NetFramework4.61测试通过。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/983668.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号