填写Word模板并使用openxml和openoffice

时间:2015-05-14 20:59:13

标签: c# openxml openoffice.org

我正在尝试使用XML中的数据填充word文档。我正在使用openXML来填充文档,该文档效果很好并将其保存为.docx。问题是我必须打开Word并将文档保存为.odt,然后使用OpenOffice SDK打开.docx并将其另存为pdf。当我不将.docx保存为.odt时,格式化已关闭。

我需要做的是能够将.docx转换为.odt或将其原始保存为.odt。

这就是我现在所拥有的:

    static void Main()
        {

            string documentText;
            XmlDocument xmlDoc = new XmlDocument(); // Create an XML document object
            xmlDoc.Load("C:\\Cache\\MMcache.xml"); // Load the XML document from the 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 the file with the 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 the Blip element of the 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 to 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 for OpenOffice. File = " + inputFile);

            StartOpenOffice();

            //Get a ComponentContext
            var xLocalContext =
                Bootstrap.bootstrap();
            //Get MultiServiceFactory
            var xRemoteFactory =
                (XMultiServiceFactory)
                xLocalContext.getServiceManager();
            //Get a CompontLoader
            var aLoader =
                (XComponentLoader)xRemoteFactory.createInstance("com.sun.star.frame.Desktop");
            //Load the sourcefile

            XComponent xComponent = null;
            try
            {
                xComponent = InitDocument(aLoader,
                                          PathConverter(inputFile), "_blank");
                //Wait for loading
                while (xComponent == null)
                {
                    Thread.Sleep(1000);
                }

                // save/export the document
                SaveDocument(xComponent, inputFile, PathConverter(outputFile));
            }
            finally
            {
                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.  Is 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 to 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 the flag for overwriting
            propertyValues[1] = new PropertyValue { Name = "Overwrite", Value = new Any(true) };
            //// Setting the 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 to 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;
            }
        }


    }

}

仅供参考,我不能使用任何使用Interop的东西,因为word不会安装在机器上。我正在使用OpenXML和OpenOffice

2 个答案:

答案 0 :(得分:0)

这就是我想要的(详情如下):  1)尝试Doc格式而不是DocX  2)切换到Libre Office并再次尝试DocX  2)使用odf-converter获得更好的DocX - &gt; ODT转换。

更多细节......

有一种称为odf-conveter(opensource)的东西,它可以转换DocX-> ODT,它可以提供(通常)比Open Office更准确的DocX-> ODT。请看OONinja的odf-conveter-integrator预装版本。

此外,Libre Office在OpenOffice之前提供了DocX支持,因此只需切换到Libre Office就可以获得更好的结果。

另一个选项是从Doc格式而不是DocX开始。在OpenOffice世界中,它更好地转换为ODT,然后转换为PDF。

希望有所帮助。

答案 1 :(得分:0)

您可以尝试使用Docxpresso直接从HTML + CSS代码生成.odt,避免任何转换问题。

Docxpresso免费用于非商业用途。