2015-05-14 6 views
0

Я пытаюсь заполнить документ Word данными из XML. Я использую openXML для заполнения документа, который отлично работает и сохраняет его как .docx. Дело в том, что я должен открыть Word и сохранить документ как .odt, а затем использовать OpenOffice SDK, чтобы открыть .docx и сохранить его как PDF. Когда я не сохраняю .docx как .odt, форматирование отключено.Заполните шаблон Word и сохраните как pdf с помощью openxml и openoffice

Что мне нужно, чтобы иметь возможность преобразовать .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 потому что слово не будет установлена ​​машина использовать. Я использую OpenXML и OpenOffice

ответ

0

Это то, что я хотел бы попробовать (подробности ниже): 1) попробовать формат Doc вместо DOCX 2) переключатель Libre Управления и попытаться DOCX снова 2) использовать ODF-преобразователю получить лучшее преобразование DocX -> ODT.

Подробнее ...

Там что-то называется ODF-Conveter (с открытым исходным кодом), который может конвертировать DocX-> ODT, который дает вам (как правило) более точные DocX-> ODT, чем Open Office. Взгляните на интегратор odf-conveter от OONinja для предварительно упакованных версий.

Кроме того, Libre Office поддерживает DocX перед OpenOffice, поэтому вы можете получить лучший результат, просто переключившись на Libre Office.

Еще один вариант - начать с формата Doc, а не DocX. В мире OpenOffice, который намного лучше переводится в ODT, а затем в PDF.

Надеюсь, что это поможет.

0

Вы можете попытаться использовать Docxpresso, чтобы сгенерировать свой .odt непосредственно из кода HTML + CSS и избежать любой проблемы с конверсией.

Docxpresso является бесплатным для некоммерческого использования.

Смежные вопросы