Programmgesteuert (C#) zu konvertieren Excel ein Bild

Möchte ich zum konvertieren einer excel-Datei in ein Bild (jedes format ist ok) programmgesteuert (c#). Derzeit bin ich mit Microsoft-Interop-Bibliotheken & Office 2007, aber es keine Unterstützung zu speichern, um ein Bild standardmäßig.

Also mein Aktueller work-around ist wie folgt:

  • Excel-Datei öffnen, die mit Microsoft Interop;
  • Finden Sie heraus, den max-Bereich (enthält Daten);
  • Verwenden Sie die CopyPicture() auf diesen Bereich, die kopieren die Daten in die Zwischenablage.

Nun der schwierige Teil (und meine Probleme):

Problem 1:

Mithilfe der .NET-Clipboard-Klasse, ich bin nicht in der Lage zu bekommen, die GENAU die kopierten Daten aus der Zwischenablage: die Daten sind die gleichen, aber irgendwie ist die Formatierung verzerrt (die schriftart des gesamten Dokuments scheint zu werden Fett und ein bisschen mehr unlesbar, während Sie waren nicht); Wenn ich das einfügen aus der Zwischenablage mit mspaint.exe das eingefügte Bild ist korrekt (und so wie ich es haben möchte).

Ich zerlegt mspaint.exe und fand eine Funktion, die es mit (OleGetClipboard), um Daten aus der Zwischenablage, aber ich kann nicht scheinen, um es funktioniert in C# /.NET.

Andere Dinge, die ich versuchte waren die Zwischenablage WINAPI (OpenClipboard, GetClipboardData, CF_ENHMETAFILE), aber die Ergebnisse waren die gleichen wie mit dem .NET-Versionen.

Problem 2:

Mithilfe der Palette und CopyPicture, ob es irgendwelche Bilder in die excel-Tabelle, die Bilder sind nicht kopiert, zusammen mit den umliegenden Daten in die Zwischenablage.

Einige der source-code

Excel.Application app = new Excel.Application();
app.Visible = app.ScreenUpdating = app.DisplayAlerts = false;
app.CopyObjectsWithCells = true;
app.CutCopyMode = Excel.XlCutCopyMode.xlCopy;
app.DisplayClipboardWindow = false;

try {
    Excel.Workbooks workbooks = null;
    Excel.Workbook book = null;
    Excel.Sheets sheets = null;

    try {
        workbooks = app.Workbooks;
        book = workbooks.Open(inputFile, false, false, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                              Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                              Type.Missing, Type.Missing);
        sheets = book.Worksheets;
    } catch {
        Cleanup(workbooks, book, sheets);   //Cleanup function calls Marshal.ReleaseComObject for all passed objects
        throw;
    }

    for (int i = 0; i < sheets.Count; i++) {
        Excel.Worksheet sheet = (Excel.Worksheet)sheets.get_Item(i + 1);

        Excel.Range myrange = sheet.UsedRange;
        Excel.Range rowRange = myrange.Rows;
        Excel.Range colRange = myrange.Columns;

        int rows = rowRange.Count;
        int cols = colRange.Count;

        //Following is used to find range with data
        string startRange = "A1";
        string endRange = ExcelColumnFromNumber(cols) + rows.ToString();

        //Skip "empty" excel sheets
        if (startRange == endRange) {
            Excel.Range firstRange = sheet.get_Range(startRange, endRange);
            Excel.Range cellRange = firstRange.Cells;
            object text = cellRange.Text;
            string strText = text.ToString();
            string trimmed = strText.Trim();

            if (trimmed == "") {
                Cleanup(trimmed, strText, text, cellRange, firstRange, myrange, rowRange, colRange, sheet);
                continue;
            }
            Cleanup(trimmed, strText, text, cellRange, firstRange);
        }

        Excel.Range range = sheet.get_Range(startRange, endRange);
        try {
            range.CopyPicture(Excel.XlPictureAppearance.xlScreen, Excel.XlCopyPictureFormat.xlPicture);

            //Problem here <-------------
            //Every attempt to get data from Clipboard fails
        } finally {
            Cleanup(range);
            Cleanup(myrange, rowRange, colRange, sheet);
        }
    }   //end for loop

    book.Close(false, Type.Missing, Type.Missing);
    workbooks.Close();

    Cleanup(book, sheets, workbooks);
} finally {
    app.Quit();
    Cleanup(app);
    GC.Collect();
}

Abrufen von Daten aus der Zwischenablage mit WINAPI erfolgreich, aber mit schlechter Qualität. Quelle:

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();
    }
}

Hat jemand eine Lösung? (Ich bin mit .NET 2.0 btw)

Könnten Sie teilen sich Ihr Quellcode? In welchem format wollen Sie die kopierten Daten? Als bitmap?

InformationsquelleAutor Zurb | 2009-08-17

Schreibe einen Kommentar