我試圖修改this example以在未安裝Office的服務器上使用來自數據庫的數據填充Word模板(無Interop)。我希望能夠從數據庫中拉出模板本身,並將生成的填充文檔存儲回數據庫。服務器生成的Word文檔將驗證但不打開
我可以上傳和下載模板文件本身,並且下載的模板仍然可以被Word讀取。但是,當我嘗試使用數據填充模板並下載生成的文檔時,當我嘗試打開文檔時收到以下錯誤:
很抱歉,我們無法打開test.docx,因爲我們發現 的內容存在問題。
詳細信息:提供
自定義XML文檔沒有錯誤的細節,item1.xml
似乎是正確的格式,並且包含正確的數據。但是也有一個item2.xml
包含以下內容:
<?xml version="1.0"?>
<b:Sources xmlns="http://schemas.openxmlformats.org/officeDocument/2006/bibliography"
xmlns:b="http://schemas.openxmlformats.org/officeDocument/2006/bibliography" Version="6" StyleName="APA"
SelectedStyle="\apasixtheditionofficeonline.xsl"/>
在XML唯一的區別懷疑我能看到的是docProps\app.xml
。在模板中有這樣的:
<Template>EquipmentOffering.dotx</Template>
<TotalTime>950</TotalTime>
<Pages>5</Pages>
<Words>2470</Words>
<Characters>14084</Characters>
<Application>Microsoft Office Word</Application>
<DocSecurity>0</DocSecurity>
<Lines>117</Lines>
<Paragraphs>33</Paragraphs>
而生成的文件中我有這樣的:
<Template>EquipmentOffering.dotx</Template>
<TotalTime>1297</TotalTime>
<Pages>1</Pages>
<Words>2486</Words>
<Characters>14176</Characters>
<Application>Microsoft Office Word</Application>
<DocSecurity>0</DocSecurity>
<Lines>118</Lines>
<Paragraphs>33</Paragraphs>
(有明顯更在該文件中,但是這是可疑的部分)
具體,<Pages>
元素讓我感到擔憂。
這是我實現的示例代碼:
Private Const strRelRoot As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
Protected Overrides Sub Execute()
'Get the parameters and the template to be filled
Dim params As CreateOfferingParams = Parameters
Dim serverWorkSpace = Application.Current.CreateDataWorkspace()
Dim offeringTemps = From sws In serverWorkSpace.myDatabase_dbData.DocTemplates
Where sws.TemplateName.Contains("EquipmentOffering")
Select sws
'Open the template and copy it into a local byte array
Dim myTemplate As DocTemplate = offeringTemps.FirstOrDefault()
Dim fileBuffer As Byte() = myTemplate.TemplateFile
'Open the file stream in memory, create a file package, and extract the relationship collection
Using pkgStream As MemoryStream = New MemoryStream(fileBuffer, True)
Using pkgFile As Package = Package.Open(pkgStream, FileMode.Open, FileAccess.ReadWrite)
Dim pkgrcOfficeDocument As PackageRelationshipCollection = pkgFile.GetRelationshipsByType(strRelRoot)
'Scan each relationship looking for custom XML
For Each pkgr As PackageRelationship In pkgrcOfficeDocument
If (pkgr.SourceUri.OriginalString = "/") Then
'Add a custom XML part to the package
Dim uriData As Uri = New Uri("/customXML/item1.xml", UriKind.Relative)
If pkgFile.PartExists(uriData) Then
'Delete template "/customXML/item1.xml" part
pkgFile.DeletePart(uriData)
End If
'Load the custom XML data
Dim pkgprtData As PackagePart = pkgFile.CreatePart(uriData, "application/xml")
Using docStream As Stream = pkgprtData.GetStream()
Using writer As XmlWriter = XmlWriter.Create(docStream)
'Write the root element and our namespace
writer.WriteStartDocument()
writer.WriteStartElement("Offering", "http://www.acrison.com")
'Write in each data element
For Each element In params.OfferingData
writer.WriteElementString(element.Key, element.Value)
Next
writer.WriteEndElement()
writer.WriteEndDocument()
End Using
End Using
End If
Next
'Rewind the stream
pkgStream.Position = 0
'Copy the modified package into a new byte array
Dim generatedOffering As Byte() = New Byte((pkgStream.Length) - 1) {}
Dim i As Integer = 0
Do While (i < pkgStream.Length)
generatedOffering(i) = CType(pkgStream.ReadByte, Byte)
i = (i + 1)
Loop
'Get the appropriate Quote entity so we have somewhere to store the newly generated file
Dim quoteInfo = From sws In serverWorkSpace.myDatabase_dbData.Quotes
Where sws.QuoteID = params.QuoteIDParam
Select sws
Dim myQuote As Quote = quoteInfo.FirstOrDefault()
'Store the file in the entity
myQuote.QuoteOffering = generatedOffering
'Save out the changes
serverWorkSpace.myDatabase_dbData.SaveChanges()
End Using
End Using
End Sub
任何人都看不到任何東西,我做錯了會導致錯位.docx
文件?
正如意見中的要求,我創建了一個簡單的三個控制模板,並試圖生成一個文件,該文件出現損壞。
Dropbox鏈接到模板文件並生成Word
.docx
。
我注意到一件奇怪的事情,雖然我這樣做了。試圖在Word 2013中打開.docx
導致上述錯誤。但Dropbox可以成功預覽它,儘管內容控件的顯示方式與沒有綁定數據一樣。我不確定這是什麼意思。
通過@Flowerking,並試圖許多例子中的解決方案出來提供的鏈接,看完後,我碰到this來得如此回答使用的Open XML 2.0和這似乎已經工作了的OP。結合我有什麼,有些什麼,我的博客鏈接閱讀,這個問題的答案,我想出了以下內容:
Protected Overrides Sub Execute()
'Get the parameters and the template to be filled
Dim params As CreateOfferingParams = Parameters
Dim serverWorkSpace = Application.Current.CreateDataWorkspace()
Dim offeringTemps = From sws In serverWorkSpace.aris_dbData.DocTemplates
Where sws.TemplateName.Contains("SimpleTest")
Select sws
'Open the template and copy it into a local byte array
Dim myTemplate As DocTemplate = offeringTemps.FirstOrDefault()
Dim fileBuffer As Byte() = myTemplate.TemplateFile
'Open the file stream in memory and create a document object from it
'Must be done this way so stream is expandable
Dim pkgStream As MemoryStream = New MemoryStream
pkgStream.Write(fileBuffer, 0, fileBuffer.Length)
Using docTemplate As WordprocessingDocument = WordprocessingDocument.Open(pkgStream, True)
'Create XML string matching custom XML part
'Extract the main part of the document and replace any custom XML
Dim mainPart As MainDocumentPart = docTemplate.MainDocumentPart
For Each part As CustomXmlPart In mainPart.CustomXmlParts
Dim docStream As New MemoryStream
Dim docWriter As XmlWriter = XmlTextWriter.Create(docStream)
'Write the declaration, root element and our namespace
docWriter.WriteStartDocument()
docWriter.WriteStartElement("Offering", "http://www.mycompany.com")
'Write in each data element
For Each element In params.OfferingData
docWriter.WriteElementString(element.Key, element.Value)
Next
'Close each of the tags and flush the stream
docWriter.WriteEndElement()
docWriter.WriteEndDocument()
docWriter.Flush()
'Rewind the stream and feed it to the custom XML part we are working on
docStream.Seek(0, SeekOrigin.Begin)
part.FeedData(docStream)
'Rewind the package stream
pkgStream.Position = 0
'Copy the modified package into a new byte array
Dim generatedOffering As Byte() = New Byte((pkgStream.Length) - 1) {}
Dim i As Integer = 0
Do While (i < pkgStream.Length)
generatedOffering(i) = CType(pkgStream.ReadByte, Byte)
i = (i + 1)
Loop
'Get the appropriate Quote entity so we have somewhere to store the newly generated file
Dim quoteInfo = From sws In serverWorkSpace.aris_dbData.Quotes
Where sws.QuoteID = params.QuoteIDParam
Select sws
Dim myQuote As Quote = quoteInfo.FirstOrDefault()
'Store the file in the entity
myQuote.QuoteOffering = generatedOffering
'Save out the changes
serverWorkSpace.aris_dbData.SaveChanges()
Next
End Using
End Sub
我相信,我只使用正確的Open XML 2.5的方法,但現在的結果是相同,我無法打開生成的.docx
。我甚至使用過Open XML SDK 2.5生產力工具,並在Word 2007,2010和2013年生成.docx
驗證。
Dropbox中的文檔已更新爲我正在使用的文檔。任何人都可以看到他們的任何錯誤?
不確定未檢查,但.docx等中的itemn.xml文件通常具有關聯的itemPropsn.xml文件以及從一個關係到另一個關係。引用的示例是舊的(2006) - 可能是爲2007版的預發佈版本編寫的,不需要這樣做? –
@bibadia Props文件確實存在。經仔細檢查,我發現它引用了錯誤的模式。但是,使用正確的架構上傳模板的最新副本並不能解決問題。 –
我不擔心頁面元素。如果您將docx放置在人們可能爲您診斷它的地方,您將增加解決此問題的可能性。或者,您可以使用Open XML Power Tools將模板與生成的docx進行比較。 – JasonPlutext