Je voudrais mettre à jour ce fil et ajouter à la réponse d'Adam ci-dessus pour le bénéfice des autres.
En fait, je réussi à pirater un code de travail ainsi que l'autre jour, (avant Adam a posté sa réponse), mais il était assez difficile. La documentation est vraiment pauvre et il n'y a pas beaucoup d'informations là-bas.
Je ne connaissais pas les Inline
et Run
éléments Adam utilise dans sa réponse, mais l'affaire semble être en arriver à la propriété Descendants<>
et vous pouvez analyser à peu près tous les éléments comme un mapping XML normal.
byte[] docBytes = File.ReadAllBytes(_myFilePath);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(docBytes, 0, docBytes.Length);
using (WordprocessingDocument wpdoc = WordprocessingDocument.Open(ms, true))
{
MainDocumentPart mainPart = wpdoc.MainDocumentPart;
Document doc = mainPart.Document;
// now you can use doc.Descendants<T>()
}
}
Une fois que vous avez ceci, il est assez facile de chercher des choses, bien que vous deviez déterminer ce que tout est appelé. Par exemple, le <pic:nvPicPr>
est Picture.NonVisualPictureProperties
, etc.
Comme Adam le dit correctement, l'élément que vous devez trouver pour remplacer l'image est l'élément Blip
. Mais vous devez trouver le bon point qui correspond à l'image que vous essayez de remplacer.
Adam montre un moyen d'utiliser l'élément Inline
. J'ai juste plongé directement et j'ai cherché tous les éléments d'image. Je ne suis pas sûr de ce qui est le meilleur ou le plus robuste (je ne sais pas à quel point la structure xml est cohérente entre les documents et si cela cause un problème de code).
Blip GetBlipForPicture(string picName, Document document)
{
return document.Descendants<Picture>()
.Where(p => picName == p.NonVisualPictureProperties.NonVisualDrawingProperties.Name)
.Select(p => p.BlipFill.Blip)
.Single(); // return First or ToList or whatever here, there can be more than one
}
Voir l'exemple XML d'Adam pour donner un sens aux différents éléments ici et voir ce que je recherche. Le blip possède un ID dans la propriété Embed
, par exemple: <a:blip r:embed="rId4" cstate="print" />
, ce qui permet de mapper le Blip à une image dans le dossier Media (vous pouvez voir tous ces dossiers et fichiers si vous renommez .docx en. zip et décompressez-le). Vous trouverez la carte dans _rels\document.xml.rels
:
<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.png" />
Alors ce que vous devez faire est d'ajouter une nouvelle image, puis pointez cette blip à l'id de l'image nouvellement créé:
// add new ImagePart
ImagePart newImg = mainPart.AddImagePart(ImagePartType.Png);
// Put image data into the ImagePart (from a filestream)
newImg .FeedData(File.Open(_myImgPath, FileMode.Open, FileAccess.Read));
// Get the blip
Blip blip = GetBlipForPicture("MyPlaceholder.png", doc);
// Point blip at new image
blip.Embed = mainPart.GetIdOfPart(newImg);
Je présume que ce n'est que la vieille image dans le dossier Media qui n'est pas idéale, bien que peut-être il est assez intelligent pour ramasser les ordures pour ainsi dire. Il y a peut-être une meilleure façon de le faire, mais je n'ai pas pu le trouver.
Quoi qu'il en soit, vous l'avez. Ce fil est maintenant la documentation la plus complète sur la façon d'échanger une image n'importe où sur le web (je sais cela, j'ai passé des heures à chercher). Donc, j'espère que certaines personnes le trouveront utile.
Adam, merci pour votre réponse. J'avais réussi à faire fonctionner quelque chose avant de poster ceci, donc j'ai ajouté quelques informations supplémentaires dans ma propre réponse ci-dessous. – fearofawhackplanet
Le second codeblock est le plus simple que j'ai trouvé jusqu'ici pour remplacer une image plutôt que d'en ajouter une nouvelle. Je voterais 2x si je le pouvais! –