Я хочу преобразовать файл excel в изображение (каждый формат в порядке) программно (С#). В настоящее время я использую библиотеки Microsoft Interop и Office 2007, но по умолчанию он не поддерживает сохранение изображения.
Итак, моя текущая работа выглядит следующим образом:
- Открыть файл Excel с помощью Microsoft Interop;
- Узнайте максимальный диапазон (содержащий данные);
- Используйте CopyPicture() в этом диапазоне, который скопирует данные в буфер обмена.
Теперь сложная часть (и мои проблемы):
Проблема 1:
Используя класс .NET Clipboard, я не могу получить EXACT скопированные данные из буфера обмена: данные одинаковые, но каким-то образом форматирование искажается (шрифт всего документа кажется полужирным, а немного нечитабельно, пока они не были); Если я вставлю из буфера обмена с помощью mspaint.exe, вставленное изображение будет правильным (и так же, как я хочу, чтобы оно было).
Я разобрал mspaint.exe и нашел функцию, которую он использует (OleGetClipboard), чтобы получить данные из буфера обмена, но я не могу заставить его работать в С#/.NET.
Другими вещами, которые я пробовал, были Clipboard WINAPI (OpenClipboard, GetClipboardData, CF_ENHMETAFILE), но результаты были такими же, как с использованием версий .NET.
Проблема 2:
Используя диапазон и CopyPicture, если на листе Excel есть какие-либо изображения, эти изображения не копируются вместе с окружающими данными в буфер обмена.
Некоторый исходный код
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();
}
Получение данных из буфера обмена с помощью WINAPI преуспевает, но с плохим качеством. Источник:
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();
}
}
Кто-нибудь получил решение? (Я использую .NET 2.0 btw)