System.InvalidOperationException:'此元素的父级为null。'

时间:2017-07-19 10:10:15

标签: c# .net-core openxml

我是新手,打开xml和我试图生成一个文字作为单词。在我的控制器中,我收到此错误:

  

System.InvalidOperationException:'此元素的父元素为空。'

这是我的控制器:

namespace Azeo.CVTheque.Controllers
{
    using DocumentFormat.OpenXml;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using Azeo.CVTheque.Framework;
    using Azeo.CVTheque.Framework.Models;
    using DocumentFormat.OpenXml.Packaging;
    using System.IO;
    using System.Text.RegularExpressions;
    using System;
    using DocumentFormat.OpenXml.Wordprocessing;
    using System.Linq;
    using System.Collections.Generic;
    using Microsoft.EntityFrameworkCore;

    [Route("api/[controller]")]
    public class GenerationController : Controller
    {
        private ApplicationContext context;
        private readonly ILogger logger;

        public GenerationController(ILogger<GenerationController> logger)
        {
            this.logger = logger;
            context = new ApplicationContext();
        }
        // GET api/word
        [HttpGet("word/{id}")]
        public void Word(int id)
        {
            try
            {
                CV cv = context.CVs.Find(id);

                string sourceFile = Path.Combine("TemplateGeneration/Template_CV_Word.dotx");
                string destinationFile = Path.Combine("CVGenerated/CV_" + cv.firstName + "_" + cv.secondName + ".docx");

                if (System.IO.File.Exists("CVGenerated/CV_" + cv.firstName + "_" + cv.secondName + ".docx"))
                {
                    System.IO.File.Delete("CVGenerated/CV_" + cv.firstName + "_" + cv.secondName + ".docx");
                }
                System.IO.File.Copy(sourceFile, destinationFile);
                using (WordprocessingDocument myDoc = WordprocessingDocument.Open(destinationFile, true))
                {
                    var mainDocumentPart = myDoc.MainDocumentPart;

                    //Body
                    var body = mainDocumentPart.Document.Body;
                    List<SdtElement> SdtBlocks = myDoc.MainDocumentPart.Document.Descendants<SdtElement>().ToList();

                    Paragraph newParagraph = new Paragraph();
                    Run newRun = new Run();
                    Text newText = new Text(cv.Resume);
                    newRun.Append(newText);
                    newParagraph.Append(newRun);
                    SdtBlocks[0].Parent.InsertBefore(newParagraph, SdtBlocks[0]);
                    SdtBlocks[0].Remove();

                    //MISSION SIGNIFICATIVE
                    Table tableSignificative = myDoc.MainDocumentPart.Document.Body.Elements<Table>().Skip(1).First();
                    SdtRow rowTemplateSignificative = tableSignificative.Elements<SdtRow>().First();
                    foreach (Mission mission in context.Missions.ToList())
                    {
                        context.Entry(mission).Collection(b => b.Taches).Query().Load();
                    }
                    var listeMission = context.CVs.Find(id).Missions.ToList();
                    foreach (Mission mission in listeMission)
                    {
                        SdtRow newRowSignificative = new SdtRow();
                        newRowSignificative = (SdtRow)rowTemplateSignificative.CloneNode(true);
                        tableSignificative.InsertAfter(newRowSignificative, rowTemplateSignificative);

                        newText = new Text(mission.Titre);
                        TableCell tc1 = newRowSignificative.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().GetFirstChild<TableCell>();
                        tc1.Descendants<Paragraph>().First().Descendants<Run>().First().ReplaceChild(newText, tc1.Descendants<Paragraph>().First().Descendants<Run>().First().Descendants<Text>().First());

                        newText = new Text(mission.DateFin.Year.ToString());
                        TableCell tc2 = newRowSignificative.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().Descendants<TableCell>().ToList()[1];
                        tc2.Descendants<Paragraph>().First().Descendants<Run>().First().ReplaceChild(newText, tc2.Descendants<Paragraph>().First().Descendants<Run>().First().Descendants<Text>().First());

                        newText = new Text(mission.Client);
                        TableCell tc3 = newRowSignificative.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().Descendants<TableCell>().ToList()[2];
                        tc3.Descendants<Paragraph>().First().Descendants<Run>().First().ReplaceChild(newText, tc3.Descendants<Paragraph>().First().Descendants<Run>().First().Descendants<Text>().First());

                        newRowSignificative.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().RemoveAllChildren<TableCell>();
                        newRowSignificative.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().InsertAfter(tc1, newRowSignificative.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().GetFirstChild<TableCell>());
                        newRowSignificative.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().Append(tc2);
                        newRowSignificative.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().Append(tc3);
                    }
                    rowTemplateSignificative.Remove();
                    myDoc.MainDocumentPart.Document.Save();

                    //Expertises
                    //On prend la table des expertises du document
                    Table tableExpertiseCompetence = myDoc.MainDocumentPart.Document.Body.Elements<Table>().Skip(2).First();
                    SdtRow rowTemplateExpertise = (SdtRow)SdtBlocks[3];

                    //On fait une recherche dans la base de données des expertises par rapport au CV
                    context.Entry(context.CVs.Find(id)).Collection(b => b.Expertises).Query().Load();
                    List<Expertise> listeExpertise = context.CVs.Find(id).Expertises.ToList();

                    //Pour chaque expertise
                    foreach (Expertise expertise in listeExpertise)
                    {
                        //Création d'une nouvelle rangée en copiant le template précédemment sauvegarder dans une variable
                        SdtRow newRowExpertise = new SdtRow();
                        newRowExpertise = (SdtRow)rowTemplateExpertise.CloneNode(true);
                        //Insertion de cette rangée dans le tableau
                        tableExpertiseCompetence.InsertAfter(newRowExpertise, rowTemplateExpertise);

                        //Création du texte dans une cellule
                        newText = new Text(expertise.Name);
                        TableCell cell = tableExpertiseCompetence.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().GetFirstChild<TableCell>();
                        cell.Descendants<Paragraph>().First().Descendants<Run>().First().ReplaceChild(newText, cell.Descendants<Paragraph>().First().Descendants<Run>().First().Descendants<Text>().First());

                        //On enleve la cellule deja présente et on ajoute la nouvelle
                        newRowExpertise.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().RemoveAllChildren<TableCell>();
                        newRowExpertise.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().InsertAfter(cell.CloneNode(true), newRowExpertise.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().GetFirstChild<TableCell>());
                    }
                    rowTemplateExpertise.Remove();
                    myDoc.MainDocumentPart.Document.Save();

                    //Competence
                    SdtRow rowTemplateCompetence = (SdtRow)SdtBlocks[5];

                    context.Entry(context.CVs.Find(id)).Collection(b => b.Competences).Query().Load();
                    List<Competence> listeCompetence = context.CVs.Find(id).Competences.ToList();

                    foreach (Competence competence in listeCompetence)
                    {
                        SdtRow newRowCompetence = new SdtRow();
                        newRowCompetence = (SdtRow)rowTemplateCompetence.CloneNode(true);
                        tableExpertiseCompetence.InsertAfter(newRowCompetence, rowTemplateCompetence);

                        newText = new Text(competence.Name);
                        TableCell cell = tableExpertiseCompetence.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().GetFirstChild<TableCell>();
                        cell.Descendants<Paragraph>().First().Descendants<Run>().First().ReplaceChild(newText, cell.Descendants<Paragraph>().First().Descendants<Run>().First().Descendants<Text>().First());

                        newRowCompetence.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().RemoveAllChildren<TableCell>();
                        newRowCompetence.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().InsertAfter(cell.CloneNode(true), newRowCompetence.SdtContentRow.GetFirstChild<SdtRow>().SdtContentRow.GetFirstChild<TableRow>().GetFirstChild<TableCell>());
                    }
                    rowTemplateCompetence.Remove();
                    myDoc.MainDocumentPart.Document.Save();

                    //Formation
                    Table tableFormation = myDoc.MainDocumentPart.Document.Body.Elements<Table>().Skip(3).First();
                    TableRow rowTemplateFormation = (TableRow)tableFormation.ToList()[3];
                    TableRow rowTemplateDiplome = (TableRow)tableFormation.ToList()[5];

                    context.Entry(context.CVs.Find(id)).Collection(b => b.Formations).Query().Load();
                    List<Formation> listeFormation = context.CVs.Find(id).Formations.ToList();

                    foreach (Formation formation in listeFormation)
                    {
                        TableRow newRowFormation = (TableRow)rowTemplateFormation.CloneNode(true);
                        tableFormation.InsertAfter(newRowFormation, rowTemplateFormation);

                        TableRow newRowDiplome = (TableRow)rowTemplateDiplome.CloneNode(true);
                        tableFormation.InsertAfter(newRowDiplome, rowTemplateDiplome);

                        newText = new Text(formation.Fin.Year.ToString() + " - " + formation.Name);
                        TableCell cell = rowTemplateFormation.Descendants<SdtCell>().First().SdtContentCell.Descendants<TableCell>().First();
                        cell.Descendants<Paragraph>().First().Descendants<Run>().First().ReplaceChild(newText, cell.Descendants<Paragraph>().First().Descendants<Run>().First().Descendants<Text>().First());
                        newRowFormation.Descendants<SdtCell>().First().Descendants<SdtContentCell>().First().ReplaceChild(cell.CloneNode(true), newRowFormation.Descendants<SdtCell>().First().Descendants<SdtContentCell>().First().GetFirstChild<TableCell>());

                        Text DiplomeText = new Text(formation.Fin.Year.ToString() + " - RENSEIGNER LE DIPLOME ICI");
                        TableCell cellDiplome = rowTemplateFormation.Descendants<SdtCell>().First().SdtContentCell.Descendants<TableCell>().First();
                        cell.Descendants<Paragraph>().First().Descendants<Run>().First().ReplaceChild(DiplomeText, cell.Descendants<Paragraph>().First().Descendants<Run>().First().Descendants<Text>().First());
                        newRowDiplome.Descendants<SdtCell>().First().Descendants<SdtContentCell>().First().Descendants<SdtCell>().First().Descendants<SdtContentCell>().First().ReplaceChild(cellDiplome.CloneNode(true), newRowDiplome.Descendants<SdtCell>().First().Descendants<SdtContentCell>().First().Descendants<SdtCell>().First().Descendants<SdtContentCell>().First().GetFirstChild<TableCell>());
                    }
                    rowTemplateFormation.Remove();
                    rowTemplateDiplome.Remove();
                    myDoc.MainDocumentPart.Document.Save();

                    //Mission
                    SdtBlock block = myDoc.MainDocumentPart.Document.Body.Elements<SdtBlock>().First();
                    Table tableMission = block.Descendants<SdtContentBlock>().First().Descendants<SdtBlock>().First().Descendants<SdtContentBlock>().First().GetFirstChild<Table>();
                    TableRow rowMissionClientDateTemplate = tableMission.Elements<TableRow>().First();
                    TableRow rowMissionTitreTemplate = tableMission.Elements<TableRow>().Skip(1).First();
                    TableRow rowMissionContexteTemplate = tableMission.Elements<TableRow>().Skip(2).First();
                    TableRow rowMissionTacheTemplate = tableMission.Elements<TableRow>().Skip(3).First();

                    //listeMission deja dispo !
                    foreach (Mission mission in listeMission)
                    {
                        //A FAIRE !
                    }
                    rowTemplateSignificative.Remove();
                    myDoc.MainDocumentPart.Document.Save();

                    //Header
                    var header = mainDocumentPart.HeaderParts;
                    List<SdtElement> elements = new List<SdtElement>();
                    foreach (var h in header)
                    {
                        elements.AddRange(h.Header.Descendants<SdtElement>());
                    }
                    foreach (SdtElement elem in elements)
                    {
                        elem.InnerXml = elem.InnerXml.Replace("Nom", cv.firstName);
                        elem.InnerXml = elem.InnerXml.Replace("Prenom", cv.secondName);
                        elem.InnerXml = elem.InnerXml.Replace("Objet", cv.objet);
                        elem.InnerXml = elem.InnerXml.Replace("NbAnnee", cv.nbAnneeExp.ToString());
                    }
                    myDoc.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
                    myDoc.MainDocumentPart.Document.Save();
                }
            }
            catch (System.Exception ex)
            {
                logger.LogError(ex.Message, ex);
                throw;
            }

        }

        // GET api/pdf
        [HttpGet("pdf/{id}")]
        public void Pdf(int id)
        {
            try
            {

            }
            catch (System.Exception ex)
            {
                logger.LogError(ex.Message, ex);
                throw;
            }
        }
    }
}

Screenshot

0 个答案:

没有答案