Cómo usar OpenXML SDK con F# y MemoryStreams
Frecuentes
Visto 707 veces
2
Este artículo dice que necesita usar MemoryStreams redimensionables cuando trabaja con OpenXML SDK, y el código de muestra funciona bien.
Sin embargo, cuando traduzco el código C# de muestra a F#, el documento permanece sin cambios:
open System.IO
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Wordprocessing
[<EntryPoint>]
let Main args =
let byteArray = File.ReadAllBytes "Test.docx"
use mem = new MemoryStream()
mem.Write(byteArray, 0, (int)byteArray.Length)
let para = new Paragraph()
let run = new Run()
let text = new Text("Newly inserted paragraph")
run.InsertAt(text, 0) |> ignore
para.InsertAt(run, 0) |> ignore
use doc = WordprocessingDocument.Open(mem, true)
doc.MainDocumentPart.Document.Body.InsertAt(para, 0) |> ignore
// no change to the document
use fs = new FileStream("Test2.docx", System.IO.FileMode.Create)
mem.WriteTo(fs)
0
Funciona bien cuando uso WordprocessingDocument.Open("Test1.docx", true)
, pero quiero usar un MemoryStream
. ¿Qué estoy haciendo mal?
1 Respuestas
4
Cambios que estás haciendo en doc
no se reflejan en MemoryStream mem
hasta que cierres doc
. Colocación doc.Close()
como a continuación
...
doc.MainDocumentPart.Document.Body.InsertAt(para, 0) |> ignore
doc.Close()
...
soluciona el problema y recibirás un mensaje de texto Newly inserted paragraph
en la parte superior de tu Test2.docx
.
Además, a su fragmento le falta una referencia obligatoria:
open DocumentFormat.OpenXml.Packaging
del WindowsBase.dll
.
EDITAR: como señaló ildjarn, más F#-idiomático sería la siguiente refactorización:
open System.IO
open System.IO.Packaging
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Wordprocessing
[<EntryPoint>]
let Main args =
let byteArray = File.ReadAllBytes "Test.docx"
use mem = new MemoryStream()
mem.Write(byteArray, 0, (int)byteArray.Length)
do
use doc = WordprocessingDocument.Open(mem, true)
let para = new Paragraph()
let run = new Run()
let text = new Text("Newly inserted paragraph")
run.InsertAt(text, 0) |> ignore
para.InsertAt(run, 0) |> ignore
doc.MainDocumentPart.Document.Body.InsertAt(para, 0) |> ignore
use fs = new FileStream("Test2.docx", FileMode.Create)
mem.WriteTo(fs)
0
contestado el 22 de mayo de 12 a las 17:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas f# openxml or haz tu propia pregunta.
Personalmente, pondría
use doc = ...
y la siguiente línea en undo
bloquear en lugar de llamarClose()
a mano. - ildjarn@mcmc: en el fragmento de MSDN C# "
doc.Close()
" se realiza implícitamente porusing (WordprocessingDocument wordDoc = ... {... }
; eliminación automática sobre la{...}
descargas de salida de bloque todos loswordDoc
datos aMemoryStream
. A su puerto F# inicial le faltaba esta sutileza. La versión refactorizada de F# aplica el mismo patrón:doc
el rubor ocurre al salirdo
envoltura de bloqueuse doc...
pieza. - gen belitski