2010-06-22 32 views
13

Tôi đang viết một hàm để xuất dữ liệu sang Excel bằng cách sử dụng Office Interop trong VB .NET. Tôi hiện đang viết các ô trực tiếp bằng cách sử dụng phương thức Cells() của trang tính Excel:Cách nhanh nhất để ghi các ô vào Excel bằng Office Interop?

worksheet.Cells(rowIndex, colIndex) = data(rowIndex)(colIndex) 

Việc này mất nhiều thời gian cho một lượng lớn dữ liệu. Có cách nào nhanh hơn để ghi nhiều dữ liệu vào Excel cùng một lúc không? Sẽ làm điều gì đó với phạm vi được nhanh hơn?

+0

Gần trùng lặp này có câu trả lời mở rộng: http://stackoverflow.com/questions/3840270/fastest-way-to-interface-between-live-unsaved-excel-data-and-c-sharp-objects. – Govert

Trả lời

28

Bạn nên tránh đọc và viết ô theo ô nếu có thể. Nó nhanh hơn nhiều khi làm việc với các mảng và đọc hoặc viết toàn bộ các khối cùng một lúc. Tôi đã viết một bài đăng một lúc trở lại trên reading from worksheets using C#; về cơ bản, cùng một mã hoạt động theo cách khác xung quanh (xem bên dưới) và sẽ chạy nhanh hơn nhiều, đặc biệt là với các khối dữ liệu lớn hơn.

var sheet = (Worksheet)Application.ActiveSheet; 
    var range = sheet.get_Range("A1", "B2"); 
    var data = new string[3,3]; 
    data[0, 0] = "A1"; 
    data[0, 1] = "B1"; 
    data[1, 0] = "A2"; 
    data[1, 1] = "B2"; 
    range.Value2 = data; 
+1

Tôi không thể để lại nhận xét trên blog của bạn, vì vậy hãy để tôi viết nó ở đây. Bạn có thể tạo một mảng dựa trên 1 trong C# bằng phương thức CreateInstance: var arr = (đối tượng [,]) Array.CreateInstance (typeof (đối tượng), new int [] {2, 3}, new int [] {1 , 1}) – IMil

10

Nếu bạn chưa có, hãy đảm bảo đặt Application.ScreenUpdating = false trước khi bạn bắt đầu xuất dữ liệu của mình. Điều này sẽ làm cho mọi thứ diễn ra nhanh hơn nhiều. Đặt nó trở lại True khi bạn hoàn thành xuất dữ liệu của mình. Việc phải vẽ lại màn hình trên mỗi lần thay đổi ô sẽ mất một chút thời gian, bỏ qua việc này sẽ tiết kiệm được điều đó.

Đối với việc sử dụng dải ô, bạn vẫn cần phải nhắm mục tiêu 1 (một) ô cụ thể cho một giá trị, vì vậy tôi không thấy lợi ích ở đây. Tôi không biết làm điều này nhanh hơn những gì bạn đang làm liên quan đến thực sự xuất dữ liệu.

5

Chỉ cần thêm vào câu trả lời của Tommy.

  • Bạn cũng có thể muốn đặt phép tính thành thủ công trước khi bắt đầu viết.

Application.Calculation = xlCalculationManual

Và đặt nó trở lại tự động khi bạn đang thực hiện với văn bản của bạn. (Nếu có một cơ hội mà chế độ ban đầu có thể là bất cứ điều gì khác hơn là tự động, bạn sẽ phải lưu trữ giá trị đó trước khi cài đặt nó vào tay)

Application.Calculation = xlCalculationAutomatic

  • Bạn cũng có thể sử dụng phương thức CopyFromRecordset của đối tượng Range.

http://msdn.microsoft.com/de-de/library/microsoft.office.interop.excel.range.copyfromrecordset(office.11).aspx

2

Thành thực mà nói, cách nhanh nhất để viết nó là với delimiters dấu phẩy. Sẽ dễ dàng hơn khi viết một dòng các trường bằng cách sử dụng phương thức Join (","). ToString thay vì cố gắng lặp qua các ô. Sau đó lưu tệp dưới dạng ".csv". Sử dụng interop, mở tệp dưới dạng csv sẽ tự động cập nhật ô cho bạn khi mở.

+3

Nếu tốc độ là những gì bạn đang sau thì đây là con đường để đi, tuy nhiên có gotchas đặc biệt là xung quanh dây và ký tự đặc biệt –

+0

Điều này sẽ làm việc nếu bạn muốn viết trong công thức? –

3

Cách nhanh nhất để viết và đọc các giá trị từ phạm vi excel là Range.get_ValueRange.set_Value.

Cách như sau:

Range filledRange = Worksheet.get_Range("A1:Z678",Missing); 
object[,] rngval = (object[,]) filledRange.get_Value (XlRangeValueDataType.xlRangeValueDefault); 

Range Destination = Worksheet2.get_Range("A1:Z678",Missing); 
destination.set_Value(Missing,rngval); 

và có, không cần lặp.Hiệu suất chỉ là voila !!

Hy vọng điều đó sẽ hữu ích !!

0

Trong trường hợp người khác đến cùng tôi tìm kiếm giải pháp đầy đủ bằng phương pháp do @Mathias cung cấp (có vẻ nhanh nhất để tải vào Excel) với đề xuất của @ IMil về Mảng.
Ở đây bạn đi:

'dt (DataTable) is the already populated DataTable 
'myExcelWorksheet (Worksheet) is the worksheet we are populating 
'rowNum (Integer) is the row we want to start from (usually 1) 
Dim misValue As Object = System.Reflection.Missing.Value 
Dim arr As Object = DataTableToArray(dt) 
'Char 65 is the letter "A" 
Dim RangeTopLeft As String = Convert.ToChar(65 + 0).ToString() + rowNum.ToString() 
Dim RangeBottomRight As String = Convert.ToChar(65 + dt.Columns.Count - 1).ToString() + (rowNum + dt.Rows.Count - 1).ToString() 
Dim Range As String = RangeTopLeft + ":" + RangeBottomRight 
myExcelWorksheet.Range(Range, misValue).NumberFormat = "@" 'Include this line to format all cells as type "Text" (optional step) 
'Assign to the worksheet 
myExcelWorksheet.Range(Range, misValue).Value2 = arr 

Sau đó

Hạn chế bao gồm chỉ cho phép 26 cột trước khi nó sẽ cần mã tốt hơn cho đến với các chữ cái giá trị phạm vi.

Các vấn đề liên quan