gpt4 book ai didi

c# - 以编程方式 (C#) 将 Excel 转换为图像

转载 作者:可可西里 更新时间:2023-11-01 09:09:41 24 4
gpt4 key购买 nike

我想以编程方式 (c#) 将 excel 文件转换为图像(每种格式都可以)。目前我正在使用 Microsoft Interop Libraries & Office 2007,但它默认不支持保存为图像。

所以我目前的解决方法如下:

  • 使用 Microsoft Interop 打开 Excel 文件;
  • 找出最大范围(包含数据);
  • 对该范围使用 CopyPicture(),这会将数据复制到剪贴板。

现在是棘手的部分(和我的问题):

问题 1:

使用 .NET 剪贴板类,我无法从剪贴板中获取精确复制的数据:数据是相同的,但不知何故格式被扭曲了(整个文档的字体似乎变得粗体和当他们不在的时候更难以阅读);如果我使用 mspaint.exe 从剪贴板粘贴,粘贴的图像是正确的(就像我想要的那样)。

我反汇编了 mspaint.exe,发现它使用 (OleGetClipboard) 从剪贴板获取数据的函数,但我似乎无法在 C#/.NET 中使用它。

我尝试的其他东西是剪贴板 WINAPI(OpenClipboard、GetClipboardData、CF_ENHMETAFILE),但结果与使用 .NET 版本相同。

问题 2:

使用 range 和 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)

最佳答案

根据我从您的问题中了解到的情况,我无法重现该问题。

我在 Excel 中手动选择了一个范围,选择了复制为图片选项如屏幕上所示位图,然后我使用以下代码用于保存剪贴板数据:

using System;
using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Drawing.Imaging;
using Excel = Microsoft.Office.Interop.Excel;

public class Program
{
[STAThread]
static void Main(string[] args)
{
Excel.Application excel = new Excel.Application();
Excel.Workbook wkb = excel.Workbooks.Add(Type.Missing);
Excel.Worksheet sheet = wkb.Worksheets[1] as Excel.Worksheet;
Excel.Range range = sheet.Cells[1, 1] as Excel.Range;
range.Formula = "Hello World";

// copy as seen when printed
range.CopyPicture(Excel.XlPictureAppearance.xlPrinter, Excel.XlCopyPictureFormat.xlPicture);

// uncomment to copy as seen on screen
//range.CopyPicture(Excel.XlPictureAppearance.xlScreen, Excel.XlCopyPictureFormat.xlBitmap);

Console.WriteLine("Please enter a full file name to save the image from the Clipboard:");
string fileName = Console.ReadLine();
using (FileStream fileStream = new FileStream(fileName, FileMode.Create))
{
if (Clipboard.ContainsData(System.Windows.DataFormats.EnhancedMetafile))
{
Metafile metafile = Clipboard.GetData(System.Windows.DataFormats.EnhancedMetafile) as Metafile;
metafile.Save(fileName);
}
else if (Clipboard.ContainsData(System.Windows.DataFormats.Bitmap))
{
BitmapSource bitmapSource = Clipboard.GetData(System.Windows.DataFormats.Bitmap) as BitmapSource;

JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
encoder.QualityLevel = 100;
encoder.Save(fileStream);
}
}
object objFalse = false;
wkb.Close(objFalse, Type.Missing, Type.Missing);
excel.Quit();
}
}

关于您的第二个问题:据我所知,在 Excel 中不可能同时选择单元格区域和图像。如果您想同时在图像中获取两者,您可能必须将 Excel 工作表打印为图像/PDF/XPS 文件。

关于c# - 以编程方式 (C#) 将 Excel 转换为图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1287879/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com