写入MS word文档 [英] Writing to MS word documents

查看:80
本文介绍了写入MS word文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的MS Word文档很少(包含表格和所有文件,就像申请表格一样)。我的要求是使用WPF桌面应用程序输入的信息填写此类文档。基本上相同的文档用于多个场合。



如何使用.Net做到这一点。我试图在需要时创建整个文档。但是对于单个文档,它有很多工作要做。有没有办法将内容注入word文档,可以作为模板。



提前谢谢。

解决方案

这是我放在项目中的一个帮助器类(在VB.NET中,你可以很容易地将它转换为C#)。这是它的工作原理:

1.创建单词模板(.dot文件)

2.将书签添加到需要设置数据的地方

3.格式化表格(目前只支持一个),设置标题等并且表格中有一个空行。该表也必须加入书签。

4.创建新的WordReport对象,设置模板名称,根据需要多次调用Add(BookmarkName,bookmarkData)

4a。如果你正在填写表格,那么在stringArray中给出列名列表

5.调用打印,你就完成了:) - 它将打开带有填充数据的word文档。



  Imports  Microsoft.Office.Interop 
Imports PADOVA.Common.Utilities

公共 WordReport
#Region构造函数
公共 Sub ()
如果书签 没什么 然后
Bookmarks = 列表( 字符串
< span class = code-keyword>结束 如果

如果 BookmarkData 没什么 然后
BookmarkData = Hashtable
结束 如果
结束 Sub
#结束地区

#Region变量
私人 logger 作为 NLog.Logger = NLog.LogManager.GetCurrentClassLogger
#End Region

#RegionProperties
Public Property Temp lateName 作为 字符串
公开 属性书签作为列表( 字符串
公共 属性 BookmarkColumns < span class =code-keyword> As Hashtable
公开 属性 BookmarkData 作为 Hashtable
公开 属性 GroupByIndex 作为 整数

公开 属性 ShowTableCount 作为 布尔 = True
#End Region

#Region助手
公共 Sub 添加(bookmarkName 作为 字符串,bookmarkData 作为 对象
如果 bookmarkName.Trim = 字符串 .Empty 然后
投掷 ArgumentException( Naziv bookmarkanemožebitiprazan!
返回
结束 如果

.Bookmarks.Add(bookmarkName)
Me .BookmarkData.Add(bookmarkName,bookmarkData)
结束 Sub

公开 Sub 添加(bookmarkName 作为 字符串,bookmarkData 作为 对象,bookmarkColumns 作为列表(< span class =code-keyword> String ))
.Add(bookmarkName,bookmarkData)

如果 bookmarkColumns IsNot Nothing 然后
如果 .BookmarkColumns 没什么 然后
.BookmarkColumns = Hashtable
结束 如果

.BookmarkColumns .Add(bookmarkName,bookmarkColumns)
结束 如果
结束 Sub

公共 Sub 添加(bookmarkName 作为 字符串,bookmarkData 作为 对象,bookmarkColumns 作为 String ())
Dim list As List( 字符串)=
< span class =code-keyword>如果 bookmarkColumns IsNot Nothing 然后
如果 list Nothing 然后
list = 列表( 字符串
结束 如果
对于 每个 s As 字符串 bookmarkColumns
list.Add(s)
下一步
结束 如果

.Add(bookmarkName,bookmarkData,list)
结束 Sub

公开 Sub Print()
如果 TemplateName.Trim = 字符串 .Empty 那么
抛出 ArgumentException( 未设置模板名称!
返回
结束 如果

如果 IO.File.Exists(TemplateName)然后
投掷 ArgumentException( 找不到给定名称的模板文件!
返回
结束 如果


Dim appWord As Word .Application = Nothing
Dim appWordDocument As Word.Document = 没什么
尝试
appWord = CType (CreateObject( Word.Application),Word.Application)
Application.DoEvents()
appWordDocument = appWord.Documents.Add( CObj (TemplateName))
Application.DoEvents()

Dim 数据作为 对象 =
Dim 书签 As Word.Bookmark = Nothing
Dim 作为列表( 字符串)= 没什么

Dim reportDataTable 作为 DataTable = 没什么

对于 每个 bm 作为 字符串 书签
bookmark = appWordDocument.Bookmarks(bm)
如果书签 没什么 然后 继续 对于

data = BookmarkData(bm)

如果 TypeOf 数据 DataTable 然后
columns = BookmarkColumns(bm)
如果 bookmar k.Range.Tables.Count = 0 然后 继续 对于

Dim 作为 Word.Table = bookmark.Range.Tables( 1

reportDataTable = DirectCast (data,DataTable)
Dim row As DataRow = Nothing
Dim lastRowValue As 字符串 = 字符串 .Empty
用于 index 作为 整数 = 0 reportDataTable.Rows.Count - 1
row = reportDataTable.Rows(index)

Dim newRow As Word.Row = table .Rows.Add(table.Rows.Last)

For i As 整数 = 1 columns.Count
' ukoliko treba grupiratipoodređenojkoloni,nije zadnji red makni gornji border
如果 i = GroupByIndex 那么
如果 NullToString(行(列(i - 1 )))。Trim = lastRowValue 然后
newRow.Cells(i).Range.Text = 字符串 .Empty

' 如果索引<> reportDataTable.Rows.Count - 1然后
Dim border As Word.Borders = newRow.Cells(i).Range.Borders
Dim border As Word.Border = border(Word.WdBorderType.wdBorderTop)
border.LineStyle = Word.WdLineStyle.wdLineStyleNone
' 结束如果
Else
newRow.Cells(i).Range.Text = NullToString(row(columns(i - 1 )))。修剪
结束 如果

lastRowValue = NullToString(ro w(列(i - 1 )))。修剪
否则
newRow .Cells(i).Range.Text = NullToString(row(columns(i - 1 )))。修剪
结束 如果
下一步
下一步

如果 ShowTableCount 那么
Dim 总计 As Word.Row = table.Rows.Last
如果 totals.Cells.Count> 1 然后
总计.Cells(totals.Cells.Count - 1 )。范围
.Text = < span class =code-string> TOTAL
.Bold = 1
结束 使用

totals.Cells(totals.Cells.Count).Range.Text = reportDataTable.Rows.Count。 ToString
结束 如果
Else
table.Rows.Last.Delete()
结束 如果
Else
' nemoj prepisivati defaultni tekst s template-a akonemaništazaupisati
If NullToString(data).Trim<> 字符串 .Empty 然后

bookmark.Range.Text = NullToString(data) .Trim
结束 如果
结束 如果
下一步

appWord.Visible = True
Application.DoEvents()

appWord.ActiveDocument.Protect(Word.WdProtectionType.wdAllowOnlyReading, False 字符串 .Empty, False False
Application.DoEvents()
Catch ex 作为异常
MsgBox( 填写报告数据时出错。,MsgBoxStyle.Exclamation)
logger。错误 {0}:{1}:{2},Now.ToString,< span class =code-string> WordReport:打印,ex)
最后
如果 appWordDocument IsNot 没什么 然后
System.Runtime.InteropServices.Marshal.ReleaseComObject(appWordDocument)
End 如果

如果 appWord IsNot 没什么 然后
系统.Runtime.InteropServices.Marshal.ReleaseComObject(appWord)
结束 如果
< span class =code-keyword>结束 尝试
结束 Sub

#End Region
结束







这就是你填写报告的方式:

 私有  Sub  IspisNepravilnosti(ispisNepravilnosti  As  DataTable)
尝试
如果 _nepravilnostZapisnikId = 0 那么 < span class =code-keyword>返回

Dim zm As ZapisniciManager(GlobalContext)
Dim zapisnik As DataSet = zm.GetZapisnik(_nepravilnostZapisnikId)

如果 zapisnik 没什么 OrElse zapisnik.Tables.Count = 0 OrElse zapisnik。表( 0 )。Rows.Count = 0 然后
MsgBox( Ispis nepravilnosti nije uspio!,MsgBoxStyle.Exclamation)
返回
结束 如果

Dim wr 作为 WordReport
使用 wr
Dim templatePath 作为 字符串 = IO.Path.Combine (ApplicationExecutablePath, wordtemplates
Dim templateFile As String = IO.Path.Combine(templatePath, IspisNepravilnosti.dot
.TemplateName = templateFile
.ShowTableCount = 错误
.GroupByIndex = 1

.Add( BrojKutije,mtxtNinIdKutije.Text.Trim .ToUpperInvariant)
.Add( BrojZapisnika,zapisnik.Tables( 0 )。行( 0 )。项目( < span class =code-string> prikaz_broja_zapisnika))


.Add( ListaNepravilnosti,ispisNepravilnosti,{ NAZIV_NEDOSTATKA,< span class =code-string> ZADUZNICE KLIJENT BROJ_OVJERE})
' 。添加(Napomena,??)

.Add( OvlasteniRadnik1,GlobalContext.ImePrezime.ToUpper)
' 。添加(OvlasteniRadnik2,)'ne koristi se,odn。 radniktrebaručnoupisati
.Add( DatumNepravilnosti,Today.ToString ( dd.MM.yyyy))


.Print()
结束 使用
Catch ex As 异常
MsgBox(ex.Message,MsgBoxStyle.Exclamation)
结束 尝试
结束


I've few MS word documents (with tables and all, it's like an application form). My requirement is to fill such documents with information entered using a WPF desktop application. Basically the same document using for multiple occasions.

How can I do this with .Net. I tried to create the whole document when required. But it has lots of work to do for a single document. Is there a way to inject the content into the word document, may be as a template.

Thanks in advance.

解决方案

Here is a helper class I put in my project (its in VB.NET, you can easily convert it to C#). This is how it works:
1. create word template (.dot file)
2. add bookmarks to places where you need to set the data
3. format the table (currently supports only one), set headers etc AND HAVE ONE EMPTY ROW of the table. The table has to be bookmarked too.
4. Create new WordReport object, set template name, call Add ("BookmarkName", bookmarkData) as many times as you need it
4a. if you're filling the table then give the list of column names in stringArray
5. Call Print and you're done :) - it will open word document with filled data.

Imports Microsoft.Office.Interop
Imports PADOVA.Common.Utilities

Public Class WordReport
#Region "Constructor"
    Public Sub New()
        If Bookmarks Is Nothing Then
            Bookmarks = New List(Of String)
        End If

        If BookmarkData Is Nothing Then
            BookmarkData = New Hashtable
        End If
    End Sub
#End Region

#Region "Variables"
    Private logger As NLog.Logger = NLog.LogManager.GetCurrentClassLogger
#End Region

#Region "Properties"
    Public Property TemplateName As String
    Public Property Bookmarks As List(Of String)
    Public Property BookmarkColumns As Hashtable
    Public Property BookmarkData As Hashtable
    Public Property GroupByIndex As Integer

    Public Property ShowTableCount As Boolean = True
#End Region

#Region "Helpers"
    Public Sub Add(bookmarkName As String, bookmarkData As Object)
        If bookmarkName.Trim = String.Empty Then
            Throw New ArgumentException("Naziv bookmarka ne može biti prazan!")
            Return
        End If

        Me.Bookmarks.Add(bookmarkName)
        Me.BookmarkData.Add(bookmarkName, bookmarkData)
    End Sub

    Public Sub Add(bookmarkName As String, bookmarkData As Object, bookmarkColumns As List(Of String))
        Me.Add(bookmarkName, bookmarkData)

        If bookmarkColumns IsNot Nothing Then
            If Me.BookmarkColumns Is Nothing Then
                Me.BookmarkColumns = New Hashtable
            End If

            Me.BookmarkColumns.Add(bookmarkName, bookmarkColumns)
        End If
    End Sub

    Public Sub Add(bookmarkName As String, bookmarkData As Object, bookmarkColumns As String())
        Dim list As List(Of String) = Nothing
        If bookmarkColumns IsNot Nothing Then
            If list Is Nothing Then
                list = New List(Of String)
            End If
            For Each s As String In bookmarkColumns
                list.Add(s)
            Next
        End If

        Me.Add(bookmarkName, bookmarkData, list)
    End Sub

    Public Sub Print()
        If TemplateName.Trim = String.Empty Then
            Throw New ArgumentException("Template name not set!")
            Return
        End If

        If Not IO.File.Exists(TemplateName) Then
            Throw New ArgumentException("Template file not found by given name!")
            Return
        End If


        Dim appWord As Word.Application = Nothing
        Dim appWordDocument As Word.Document = Nothing
        Try
            appWord = CType(CreateObject("Word.Application"), Word.Application)
            Application.DoEvents()
            appWordDocument = appWord.Documents.Add(CObj(TemplateName))
            Application.DoEvents()

            Dim data As Object = Nothing
            Dim bookmark As Word.Bookmark = Nothing
            Dim columns As List(Of String) = Nothing

            Dim reportDataTable As DataTable = Nothing

            For Each bm As String In Bookmarks
                bookmark = appWordDocument.Bookmarks(bm)
                If bookmark Is Nothing Then Continue For

                data = BookmarkData(bm)

                If TypeOf data Is DataTable Then
                    columns = BookmarkColumns(bm)
                    If bookmark.Range.Tables.Count = 0 Then Continue For

                    Dim table As Word.Table = bookmark.Range.Tables(1)

                    reportDataTable = DirectCast(data, DataTable)
                    Dim row As DataRow = Nothing
                    Dim lastRowValue As String = String.Empty
                    For index As Integer = 0 To reportDataTable.Rows.Count - 1
                        row = reportDataTable.Rows(index)

                        Dim newRow As Word.Row = table.Rows.Add(table.Rows.Last)

                        For i As Integer = 1 To columns.Count
                            ' ukoliko treba grupirati po određenoj koloni, a nije zadnji red makni gornji border
                            If i = GroupByIndex Then
                                If NullToString(row(columns(i - 1))).Trim = lastRowValue Then
                                    newRow.Cells(i).Range.Text = String.Empty

                                    'If index <> reportDataTable.Rows.Count - 1 Then
                                    Dim borders As Word.Borders = newRow.Cells(i).Range.Borders
                                    Dim border As Word.Border = borders(Word.WdBorderType.wdBorderTop)
                                    border.LineStyle = Word.WdLineStyle.wdLineStyleNone
                                    'End If
                                Else
                                    newRow.Cells(i).Range.Text = NullToString(row(columns(i - 1))).Trim
                                End If

                                lastRowValue = NullToString(row(columns(i - 1))).Trim
                            Else
                                newRow.Cells(i).Range.Text = NullToString(row(columns(i - 1))).Trim
                            End If
            Next
                    Next

                    If ShowTableCount Then
                        Dim totals As Word.Row = table.Rows.Last
                        If totals.Cells.Count > 1 Then
                            With totals.Cells(totals.Cells.Count - 1).Range
                                .Text = "TOTAL"
                                .Bold = 1
                            End With

                            totals.Cells(totals.Cells.Count).Range.Text = reportDataTable.Rows.Count.ToString
                        End If
                    Else
                        table.Rows.Last.Delete()
                    End If
                Else
                    ' nemoj prepisivati defaultni tekst s template-a ako nema ništa za upisati
                    If NullToString(data).Trim <> String.Empty Then

                        bookmark.Range.Text = NullToString(data).Trim
                    End If
                End If
            Next

            appWord.Visible = True
            Application.DoEvents()

            appWord.ActiveDocument.Protect(Word.WdProtectionType.wdAllowOnlyReading, False, String.Empty, False, False)
            Application.DoEvents()
        Catch ex As Exception
            MsgBox("Error in filling the report data.", MsgBoxStyle.Exclamation)
            logger.Error("{0}: {1}: {2}", Now.ToString, "WordReport:Print", ex)
        Finally
            If appWordDocument IsNot Nothing Then
                System.Runtime.InteropServices.Marshal.ReleaseComObject(appWordDocument)
            End If

            If appWord IsNot Nothing Then
                System.Runtime.InteropServices.Marshal.ReleaseComObject(appWord)
            End If
        End Try
    End Sub

#End Region
End Class




This is how you're filling the report:

Private Sub IspisNepravilnosti(ispisNepravilnosti As DataTable)
        Try
            If _nepravilnostZapisnikId = 0 Then Return

            Dim zm As New ZapisniciManager(GlobalContext)
            Dim zapisnik As DataSet = zm.GetZapisnik(_nepravilnostZapisnikId)

            If zapisnik Is Nothing OrElse zapisnik.Tables.Count = 0 OrElse zapisnik.Tables(0).Rows.Count = 0 Then
                MsgBox("Ispis nepravilnosti nije uspio!", MsgBoxStyle.Exclamation)
                Return
            End If

            Dim wr As New WordReport
            With wr
                Dim templatePath As String = IO.Path.Combine(ApplicationExecutablePath, "wordtemplates")
                Dim templateFile As String = IO.Path.Combine(templatePath, "IspisNepravilnosti.dot")
                .TemplateName = templateFile
                .ShowTableCount = False
                .GroupByIndex = 1

                .Add("BrojKutije", mtxtNinIdKutije.Text.Trim.ToUpperInvariant)
                .Add("BrojZapisnika", zapisnik.Tables(0).Rows(0).Item("prikaz_broja_zapisnika"))


                .Add("ListaNepravilnosti", ispisNepravilnosti, {"NAZIV_NEDOSTATKA", "ZADUZNICE", "KLIJENT", "BROJ_OVJERE"})
                '.Add("Napomena", "??")

                .Add("OvlasteniRadnik1", GlobalContext.ImePrezime.ToUpper)
                '.Add("OvlasteniRadnik2", "") ' ne koristi se, odn. radnik treba ručno upisati
                .Add("DatumNepravilnosti", Today.ToString("dd.MM.yyyy"))


                .Print()
            End With
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Exclamation)
        End Try
    End Sub


这篇关于写入MS word文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆