2012-06-28 23 views
5

Ho un problema con l'analisi del documento * .docx con OpenXML (C#).Tabella di estrazione da DOCX

Quindi, ecco i miei passi:
1. Caricare documento * .docx
2. Ricevere lista dei paragrafi
3. In ogni aspetto paragrafo per elementi di testo, immagini e tabella
4. Per ogni testo e image element creare tag html
5. Salvare l'output come file * .html

Ho scoperto come individuare il file di immagine nel documento ed estrarlo. Ora c'è un passo da fare - trova dove è la posizione della tabella nel testo (paragrafo).

Se qualcuno sa come individuare la tabella nel documento * .docx utilizzando OpenXML, si prega di aiutare. Grazie.

In aggiunta: Ok, potrebbe essere che non so spiegare cosa intendo. Se si ottiene il contenuto del paragrafo, è possibile trovare oggetti di ricerca come blocchi di testo, immagini e così via. Quindi, se il paragrafo contiene Run che contiene Picture, significa che in questo posto nell'immagine posizionata del documento Word.

Esempio di mia funzione:

public static string ParseDocxDocument(string pathToFile) 
    { 
     StringBuilder result = new StringBuilder(); 
     WordprocessingDocument wordProcessingDoc = WordprocessingDocument.Open(pathToFile, true); 
     List<ImagePart> imgPart = wordProcessingDoc.MainDocumentPart.ImageParts.ToList(); 
     IEnumerable<Paragraph> paragraphElement = wordProcessingDoc.MainDocumentPart.Document.Descendants<Paragraph>(); 
     int imgCounter = 0; 


     foreach (Paragraph par in paragraphElement) 
     { 

       //Add new paragraph tag 
       result.Append("<div style=\"width:100%; text-align:"); 

       //Append anchor style 
       if (par.ParagraphProperties != null && par.ParagraphProperties.Justification != null) 
        switch (par.ParagraphProperties.Justification.Val.Value) 
        { 
         case JustificationValues.Left: 
          result.Append("left;"); 
          break; 
         case JustificationValues.Center: 
          result.Append("center;"); 
          break; 
         case JustificationValues.Both: 
          result.Append("justify;"); 
          break; 
         case JustificationValues.Right: 
         default: 
          result.Append("right;"); 
          break; 
        } 
       else 
        result.Append("left;"); 

       //Append text decoration style 
       if (par.ParagraphProperties != null && par.ParagraphProperties.ParagraphMarkRunProperties != null && par.ParagraphProperties.ParagraphMarkRunProperties.HasChildren) 
        foreach (OpenXmlElement chield in par.ParagraphProperties.ParagraphMarkRunProperties.ChildElements) 
        { 
         switch (chield.GetType().Name) 
         { 
          case "Bold": 
           result.Append("font-weight:bold;"); 
           break; 
          case "Underline": 
           result.Append("text-decoration:underline;"); 
           break; 
          case "Italic": 
           result.Append("font-style:italic;"); 
           break; 
          case "FontSize": 
           result.Append("font-size:" + ((FontSize)chield).Val.Value + "px;"); 
           break; 
          default: break; 
         } 
        } 

       result.Append("\">"); 

       //Add image tag 
       IEnumerable<Run> runs = par.Descendants<Run>(); 
       foreach (Run run in runs) 
       { 
        if (run.HasChildren) 
        { 
         foreach (OpenXmlElement chield in run.ChildElements.Where(o => o.GetType().Name == "Picture")) 
         { 
          result.Append(string.Format("<img style=\"{1}\" src=\"data:image/jpeg;base64,{0}\" />", GetBase64Image(imgPart[imgCounter].GetStream()), 
              ((DocumentFormat.OpenXml.Vml.Shape)chield.ChildElements.Where(o => o.GetType().Name == "Shape").FirstOrDefault()).Style 
           )); 
          imgCounter++; 
         } 
        } 
       } 

       //Append inner text 
       IEnumerable<Text> textElement = par.Descendants<Text>(); 
       if (par.Descendants<Text>().Count() == 0) 
        result.Append("<br />"); 

       foreach (Text t in textElement) 
       { 
        result.Append(t.Text); 
       } 


       result.Append("</div>"); 
       result.Append(Environment.NewLine); 

     } 

     wordProcessingDoc.Close(); 

     return result.ToString(); 
    } 

Ora whant specificare posto della tabella nel testo (come apparire in Word).

finale:

Ok, tutti, ho scoperto. Nella mia funzione di esempio un grande errore. Sono elencati gli elementi del paragrafo del corpo del documento. Le tabelle sono allo stesso livello di Paragrafo, quindi la funzione ignora le tabelle. Quindi dobbiamo enumerare gli elementi del corpo del documento.

Ecco la mia funzione di test per generare correttezza del codice HTML da docx (è solo codice di test, quindi non è pulito)

public static string ParseDocxDocument(string pathToFile) 
    { 
     StringBuilder result = new StringBuilder(); 
     WordprocessingDocument wordProcessingDoc = WordprocessingDocument.Open(pathToFile, true); 
     List<ImagePart> imgPart = wordProcessingDoc.MainDocumentPart.ImageParts.ToList(); 
     List<string> tableCellContent = new List<string>(); 
     IEnumerable<Paragraph> paragraphElement = wordProcessingDoc.MainDocumentPart.Document.Descendants<Paragraph>(); 
     int imgCounter = 0; 

     foreach (OpenXmlElement section in wordProcessingDoc.MainDocumentPart.Document.Body.Elements<OpenXmlElement>()) 
     { 
      if(section.GetType().Name == "Paragraph") 
      { 
       Paragraph par = (Paragraph)section; 
       //Add new paragraph tag 
       result.Append("<div style=\"width:100%; text-align:"); 

       //Append anchor style 
       if (par.ParagraphProperties != null && par.ParagraphProperties.Justification != null) 
        switch (par.ParagraphProperties.Justification.Val.Value) 
        { 
         case JustificationValues.Left: 
          result.Append("left;"); 
          break; 
         case JustificationValues.Center: 
          result.Append("center;"); 
          break; 
         case JustificationValues.Both: 
          result.Append("justify;"); 
          break; 
         case JustificationValues.Right: 
         default: 
          result.Append("right;"); 
          break; 
        } 
       else 
        result.Append("left;"); 

       //Append text decoration style 
       if (par.ParagraphProperties != null && par.ParagraphProperties.ParagraphMarkRunProperties != null && par.ParagraphProperties.ParagraphMarkRunProperties.HasChildren) 
        foreach (OpenXmlElement chield in par.ParagraphProperties.ParagraphMarkRunProperties.ChildElements) 
        { 
         switch (chield.GetType().Name) 
         { 
          case "Bold": 
           result.Append("font-weight:bold;"); 
           break; 
          case "Underline": 
           result.Append("text-decoration:underline;"); 
           break; 
          case "Italic": 
           result.Append("font-style:italic;"); 
           break; 
          case "FontSize": 
           result.Append("font-size:" + ((FontSize)chield).Val.Value + "px;"); 
           break; 
          default: break; 
         } 
        } 

       result.Append("\">"); 

       //Add image tag 
       IEnumerable<Run> runs = par.Descendants<Run>(); 
       foreach (Run run in runs) 
       { 
        if (run.HasChildren) 
        { 
         foreach (OpenXmlElement chield in run.ChildElements.Where(o => o.GetType().Name == "Picture")) 
         { 
          result.Append(string.Format("<img style=\"{1}\" src=\"data:image/jpeg;base64,{0}\" />", GetBase64Image(imgPart[imgCounter].GetStream()), 
              ((DocumentFormat.OpenXml.Vml.Shape)chield.ChildElements.Where(o => o.GetType().Name == "Shape").FirstOrDefault()).Style 
           )); 
          imgCounter++; 
         } 
         foreach (OpenXmlElement table in run.ChildElements.Where(o => o.GetType().Name == "Table")) 
         { 
          result.Append("<strong>HERE'S TABLE</strong>"); 
         } 
        } 
       } 

       //Append inner text 
       IEnumerable<Text> textElement = par.Descendants<Text>(); 
       if (par.Descendants<Text>().Count() == 0) 
        result.Append("<br />"); 

       foreach (Text t in textElement.Where(o=>!tableCellContent.Contains(o.Text.Trim()))) 
       { 
        result.Append(t.Text); 
       } 


       result.Append("</div>"); 
       result.Append(Environment.NewLine); 

      } 
      else if (section.GetType().Name=="Table") 
      { 
       result.Append("<table>"); 
       Table tab = (Table)section; 
       foreach (TableRow row in tab.Descendants<TableRow>()) 
       { 
        result.Append("<tr>"); 
        foreach (TableCell cell in row.Descendants<TableCell>()) 
        { 
         result.Append("<td>"); 
         result.Append(cell.InnerText); 
         tableCellContent.Add(cell.InnerText.Trim()); 
         result.Append("</td>"); 
        } 
        result.Append("</tr>"); 
       } 
       result.Append("</table>"); 
      }     
     } 


     wordProcessingDoc.Close(); 

     return result.ToString(); 
    } 

    private static string GetBase64Image(Stream inputData) 
    { 
     byte[] data = new byte[inputData.Length]; 
     inputData.Read(data, 0, data.Length); 
     return Convert.ToBase64String(data); 
    } 

risposta

1

prova a seguire per trovare la prima tabella del documento.

Table table = doc.MainDocumentPart.Document.Body.Elements<Table>().First(); 
+0

Ho imparato a leggere e analizzare i tavoli. La mia domanda è come trovare il testo di tiding insite – EkzoMan

+0

Ho aggiunto il mio codice di lavoro. Il tuo post mi dà la giusta direzione per lavorare, quindi contrassegno la tua risposta come corretta – EkzoMan