11
votes

Programmatiquement (C #) Convertissez Excel vers une image

Je veux convertir un fichier Excel en une image (chaque format est OK) de manière programmatique (C #). Actuellement, j'utilise Microsoft Interop Bibliothèques et Office 2007, mais cela ne prend pas en charge l'enregistrement d'une image par défaut.

Donc, mon travail actuel est le suivant: P>

  • Ouvrez le fichier Excel à l'aide de Microsoft Interop; Li>
  • Découvrez la plage maximale (contenant des données); li>
  • Utilisez le copicicateur () sur cette plage, qui copiera les données dans le presse-papiers. LI> ul>

    Maintenant la partie délicate (et mes problèmes): p>

    Problème 1: strong> p>

    Utilisation de la classe de presse-papiers .NET, je ' M ne pas capable d'obtenir les données copiées exactes du presse-papiers: les données sont identiques, mais la forme de la mise en forme est déformée (la police de l'ensemble du document semble devenir audacieuse et un peu plus illisible pendant qu'ils n'étaient pas); Si je colle du presse-papiers à l'aide de MSPaint.exe, l'image collé est correcte (et tout comme je le veux). P>

    J'ai démonté MSPaint.exe et j'ai trouvé une fonction utilisée (OlegetCliPboard) pour obtenir des données dans le presse-papiers, mais je ne peux pas sembler le faire fonctionner en C # / .NET. P>

    Autres choses que j'ai essayées étaient le presse-papiers Winapi's (OpenCliPboard, GetClipboardData, CF_ENHMETATIFILE), mais les résultats étaient les mêmes que d'utiliser les versions .NET. P>

    Problème 2: strong> P >

    Utilisation de la plage et de la copicicité, s'il existe des images dans la feuille Excel, ces images ne sont pas copiées avec les données environnantes dans le presse-papiers. p>

    une partie du code source p> xxx pré>

    obtenir des données du presse-papiers à l'aide de Winapi réussit, mais avec une mauvaise qualité. Source: P>

    protected virtual void ClipboardToPNG(string filename) {
        if (OpenClipboard(IntPtr.Zero)) {
            if (IsClipboardFormatAvailable((int)CLIPFORMAT.CF_ENHMETAFILE)) {
                int hEmfClp = GetClipboardDataA((int)CLIPFORMAT.CF_ENHMETAFILE);
    
                if (hEmfClp != 0) {
                    int hEmfCopy = CopyEnhMetaFileA(hEmfClp, null);
    
                    if (hEmfCopy != 0) {
                        Metafile metafile = new Metafile(new IntPtr(hEmfCopy), true);
    
                        metafile.Save(filename, ImageFormat.Png);
                    }
                }
            }
    
            CloseClipboard();
        }
    }
    


1 commentaires

Pourriez-vous partager votre code source? Dans quel format voulez-vous obtenir les données copiées? Comme bitmap?


6 Réponses :


4
votes

de ce que je comprends de votre question, je ne suis pas en mesure de reproduire le problème.

J'ai sélectionné une plage manuellement dans Excel, a choisi copier comme image avec les options comme indiqué sur Écran et bitmap sélectionné, puis j'ai utilisé le code suivant pour enregistrer les données du presse-papiers: xxx

concernant votre deuxième problème: aussi loin Comme je sais que cela n'est pas possible dans Excel de sélectionner à la fois une plage de cellules et une image en même temps. Si vous souhaitez obtenir les deux dans une image en même temps, vous devrez peut-être imprimer la feuille Excel vers un fichier image / pdf / xps.


6 commentaires

Merci de mettre à jour. Dans mon cas, clipboard.Containsdata (DataFormats.EnHeadMettafile) renvoie true, mais le presse-papiers.getData (DataFORMATS.ENHEDMETAFILE) revient toujours NULL. mspaint.exe (comme toujours) est capable de coller les données copiées dans le presse-papiers par copicicture ()


@Zurb: obtenez-vous null à partir de clipboard.getdata lorsque vous exécutez le code exemple ci-dessus? Notez qu'il utilise la classe du presse-papier WPF dans system.windows et non celle des formulaires Windows. Pouvez-vous vérifier qu'aucune autre application ne verrouille le presse-papiers?


@Divo: J'ai oublié de mentionner que j'utilise .net 2.0, je ne peux donc pas exécuter votre code complètement tel que posté. J'ai ajouté une partie de mon code source à la question.


Je reçois des données de presse-papiers, mais lorsque vous essayez de l'enregistrer, une exception "GENIC GDI +" se produit


FWIW, j'ai expérimenté la fonction de copicicité sur plusieurs systèmes avec différentes versions d'Excel (2000, 2003, 2007 et 2010). La combinaison XLScreen, XLBITMAP a toujours produit une meilleure image que XLPRINTER, XLPICTURE.


A exécuté ce code sur la version 15 de Interop et il jette la "erreur générique survenue dans gdi +" de Intersopservices.externalException. Il existe des moyens de contourner cela comme mentionné dans Stackoverflow.com/questions/15571022 mais cela ne crée qu'une png vide dans mon cas.



3
votes

tableureearer pour .NET le fera.

Vous pouvez voir notre ASP.NET (C # et VB) " Samples d'imagerie Excel et de la plage " Samples ici et téléchargez une version d'essai gratuite ici si vous voulez l'essayer.

SpreadsheetArear fonctionne également avec des formulaires Windows, des applications de console, etc. (vous n'avez pas spécifié de quel type d'application crée). Il existe également un contrôle des formulaires Windows pour afficher un classeur dans votre application si c'est ce que vous êtes vraiment après.

Clause de non-responsabilité: I Possédez à la feuille de calcul LLC


0 commentaires

1
votes

Parce que le fil ASP.NET n'a pas le bon appartement pour accéder à une classe de presse-papiers, vous devez donc écrire du code pour accéder au presse-papiers dans le nouveau fil. Par exemple: xxx

dans le fil principal: xxx


2 commentaires

Le code que j'ai publié a été mis en œuvre pour travailler dans une application de formulaire Windows C # standard (toujours ne fonctionne pas BTW), bien que je prévoyais de l'utiliser sur le Web. Merci quand même.


Je peux confirmer que l'utilisation de ces œuvres pour une solution Web.



0
votes

Fait intéressant, je l'ai fait dans un compartiment STA pendant un certain temps avec succès. J'ai écrit une application qui fonctionne sur une base hebdomadaire et des rapports d'état de projet, dont certains graphiques que je génètes de manière programmatique à l'aide d'Excel.

La nuit dernière, cela a échoué les graphiques tous renvoyés null. Je débobile aujourd'hui et ne trouvez aucune explication que le presse-papiers de méthode.GetImage () renvoie soudainement NULL. En définissant un point d'arrêt à cet appel, je peux démontrer efficacement (en appuyant sur Ctrl + V dans MS-Word) que l'image est en effet dans le Presse-papiers. Hélas continue sur le presse-papiers.GetImage () renvoie NULL (que je slips comme ça ou pas).

Mon code est exécuté sous forme d'application de console et la méthode principale a l'attribut [STATHREAD]. Je le débogère comme une application Windows Forms (tout mon code est dans une bibliothèque et j'en ai simplement deux extrémités avant).

Les deux renvoient null aujourd'hui.

Détenteurs d'intérêt, j'ai roulé de l'extratère de graphique dans un fil tel que décrit (et notez que le threadmartement est obsolète), et il fonctionne doux, mais toujours, des nulls sont retournés.

Eh bien, j'ai abandonné et j'ai fait ce que tout geek ferait, redémaçait.

voila ... tout était bon. Go Figure ... Est-ce la raison pour laquelle nous détestaons tous les ordinateurs, Microsoft Windows et Microsoft Office? Hmmmm ... il y a quelque chose, quelque chose de tout à fait transitoire qui peut vous arriver à votre PC qui fait du presse-papiers presse-papiers.GetImage () échouez!


0 commentaires

1
votes

Ceci est un bug avec GDI + lorsqu'il s'agit de convertir des métafiles en un format de carte de bit.
Cela arrive pour de nombreux EMFS qui affiche des diagrammes avec des textes. Pour recréer, vous devez simplement créer un graphique dans Excel qui affiche des données pour son axe X et Y. Copiez le graphique en tant qu'image et collez en mot comme métafile. Ouvrez le DOCX et vous verrez un EMF dans le dossier Media. Si vous ouvrez maintenant que EMF dans n'importe quel programme de peinture Windows basé sur Windows qui le convertit vers un bitmap, vous verrez des distorsions, en particulier, le texte et les lignes deviennent plus grandes et déformées. Malheureusement, c'est l'une de ces questions que Microsoft n'est pas susceptible d'admettre ou de faire quoi que ce soit. Espérons que Google et Apple reprennent bientôt le monde de la transformation du bureau / des mots.


0 commentaires

0
votes

Si cela ne vous dérange pas Linux (style), vous pouvez utiliser OpenOffice (ou LibreOffice) pour convertir le XLS en premier vers PDF, puis utilisez ImageMagic pour convertir le PDF en image. Un guide de base peut être trouvé sur http: // www. Novell.com/communities/node/5744/c-Linux-thumbnail-Generation-PDFDOCPPTXLSImages .

En outre, il semble y avoir des API .NET pour les deux programmes mentionnés ci-dessus. Voir: http://www.opendocument4all.com/download/openoffice.net.pdf et http://imagemagick.net/script/api.php#dot-net


0 commentaires