c# - Fill in Word template and save as pdf using openxml and openoffice -
i trying fill word document data xml. using openxml fill document, works great , save .docx. thing have open word , save document .odt , use openoffice sdk open .docx , save pdf. when don't save .docx .odt, formatting off.
what need able able either convert .docx .odt or save .odt.
here have right now:
static void main() { string documenttext; xmldocument xmldoc = new xmldocument(); // create xml document object xmldoc.load("c:\\cache\\mmcache.xml"); // load xml document specified file xmlnodelist patientfirst = xmldoc.getelementsbytagname("patientfirst"); xmlnodelist patientsignatureimg = xmldoc.getelementsbytagname("patientsignatureimg"); byte[] bytearray = file.readallbytes("c:\\cache\\transportationrunreporttemplate.docx"); using (memorystream stream = new memorystream()) { stream.write(bytearray, 0, (int)bytearray.length); using (wordprocessingdocument worddoc = wordprocessingdocument.open(stream, true)) { using (streamreader reader = new streamreader(worddoc.maindocumentpart.getstream())) { documenttext = reader.readtoend(); } using (streamwriter writer = new streamwriter(worddoc.maindocumentpart.getstream(filemode.create))) { writer.write(documenttext); } } // save file new name file.writeallbytes("c:\\cache\\myfinishedtemplate.docx", stream.toarray()); } } private static void addpicture(bitmap bitmap) { using (wordprocessingdocument doc = wordprocessingdocument.open("c:\\cache\\myfinishedtemplate.docx", true)) { //bitmap image = new bitmap("c:\\cache\\scribus.jpg"); sdtelement controlblock = doc.maindocumentpart.document.body .descendants<sdtelement>() .where (r => r.sdtproperties.getfirstchild<tag>().val == "signature" ).singleordefault(); // find blip element of content control. a.blip blip = controlblock.descendants<a.blip>().firstordefault(); imagepart imagepart = doc.maindocumentpart .addimagepart(imageparttype.jpeg); using (memorystream stream = new memorystream()) { bitmap.save(stream, imageformat.jpeg); stream.position = 0; imagepart.feeddata(stream); } blip.embed = doc.maindocumentpart.getidofpart(imagepart); /* dw.inline inline = controlblock .descendants<dw.inline>().firstordefault(); // 9525 = pixels points inline.extent.cy = image.size.height * 9525; inline.extent.cx = image.size.width * 9525; pic.picture pic = inline .descendants<pic.picture>().firstordefault(); pic.shapeproperties.transform2d.extents.cy = image.size.height * 9525; pic.shapeproperties.transform2d.extents.cx = image.size.width * 9525;*/ } converttopdf(@"c:\cache\myfinishedtemplate2.docx",@"c:\cache\openpdf.pdf"); } public static bitmap base64stringtobitmap(string base64string) { bitmap bmpreturn = null; byte[] bytebuffer = convert.frombase64string(base64string); memorystream memorystream = new memorystream(bytebuffer); memorystream.position = 0; bmpreturn = (bitmap)bitmap.fromstream(memorystream); memorystream.close(); memorystream = null; bytebuffer = null; return bmpreturn; } public static void converttopdf(string inputfile, string outputfile) { if (convertextensiontofiltertype(system.io.path.getextension(inputfile)) == null) throw new invalidprogramexception("unknown file type openoffice. file = " + inputfile); startopenoffice(); //get componentcontext var xlocalcontext = bootstrap.bootstrap(); //get multiservicefactory var xremotefactory = (xmultiservicefactory) xlocalcontext.getservicemanager(); //get compontloader var aloader = (xcomponentloader)xremotefactory.createinstance("com.sun.star.frame.desktop"); //load sourcefile xcomponent xcomponent = null; try { xcomponent = initdocument(aloader, pathconverter(inputfile), "_blank"); //wait loading while (xcomponent == null) { thread.sleep(1000); } // save/export document savedocument(xcomponent, inputfile, pathconverter(outputfile)); } { if (xcomponent != null) xcomponent.dispose(); } } private static void startopenoffice() { var ps = process.getprocessesbyname("soffice.exe"); if (ps.length != 0) throw new invalidprogramexception("openoffice not found. openoffice installed?"); if (ps.length > 0) return; var p = new process { startinfo = { arguments = "-headless -nofirststartwizard", filename = "soffice.exe", createnowindow = true } }; var result = p.start(); if (result == false) throw new invalidprogramexception("openoffice failed start."); } private static xcomponent initdocument(xcomponentloader aloader, string file, string target) { var openprops = new propertyvalue[1]; openprops[0] = new propertyvalue { name = "hidden", value = new any(true) }; xcomponent xcomponent = aloader.loadcomponentfromurl( file, target, 0, openprops); return xcomponent; } private static void savedocument(xcomponent xcomponent, string sourcefile, string destinationfile) { var propertyvalues = new propertyvalue[2]; // setting flag overwriting propertyvalues[1] = new propertyvalue { name = "overwrite", value = new any(true) }; //// setting filter name propertyvalues[0] = new propertyvalue { name = "filtername", value = new any(convertextensiontofiltertype(system.io.path.getextension(sourcefile))) }; ((xstorable)xcomponent).storetourl(destinationfile, propertyvalues); } private static string pathconverter(string file) { if (file == null || file.length == 0) throw new nullreferenceexception("null or empty path passed openoffice"); return string.format("file:///{0}", file.replace(@"\", "/")); } public static string convertextensiontofiltertype(string extension) { switch (extension) { case ".odt": case ".doc": case ".docx": case ".txt": case ".rtf": case ".html": case ".htm": case ".xml": case ".wps": case ".wpd": return "writer_pdf_export"; case ".xls": case ".xlsb": case ".ods": return "calc_pdf_export"; case ".ppt": case ".pptx": case ".odp": return "impress_pdf_export"; default: return null; } } } }
just information cannot use uses interop because word not installed machine. using openxml , openoffice
this try (details below): 1) try doc format instead of docx 2) switch libre office , try docx again 2) use odf-converter better docx -> odt conversion.
more details...
there's called odf-conveter (opensource) can convert docx->odt gives (typically) more accurate docx->odt open office. take @ odf-conveter-integrator ooninja pre-packaged versions.
also, libre office has docx support ahead of openoffice might better result switching libre office.
a further option start doc format rather docx. in openoffice world translates better odt , pdf.
hope helps.
Comments
Post a Comment