【问题标题】:Fill in Word template and save as pdf using openxml and openoffice使用openxml和openoffice填写Word模板并保存为pdf
【发布时间】:2015-07-26 15:41:41
【问题描述】:

我正在尝试使用 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

【问题讨论】:

    标签: c# openxml openoffice.org


    【解决方案1】:

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

    更多细节...

    有一种叫做 odf-conveter(开源)的东西可以转换 DocX->ODT,它给你(通常)比 Open Office 更准确的 DocX->ODT。查看 OONinja 的 odf-conveter-integrator 以获得预打包版本。

    此外,Libre Office 在 OpenOffice 之前支持 DocX,因此您只需切换到 Libre Office 即可获得更好的结果。

    另一种选择是从 Doc 格式而不是 DocX 开始。在 OpenOffice 世界中,转换为 ODT 和 PDF 的效果要好得多。

    希望对您有所帮助。

    【讨论】:

      【解决方案2】:

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

      Docxpresso 可免费用于非商业用途。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-14
        • 1970-01-01
        • 2010-11-17
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多