Đôi khi sản phẩm bàn giao không phải một tài liệu, mà là một bức ảnh của một bảng. Một khối tóm tắt trong email trạng thái, một bảng KPI được kết xuất trong dashboard, một thumbnail cạnh kết quả tìm kiếm: tất cả đều muốn các ô và chẳng cái nào muốn giấy. TXLSCellImageExporter trong HotXLS nhận một hình chữ nhật ô kiểu cổ điển hay XLSX và tạo ra một PNG hay JPEG gọn gàng mà không có cỡ trang, lề, đầu trang hay chân trang, tiêu đề in, hay ngắt trang. Độ phân giải, tỉ lệ, định dạng và chất lượng JPEG cấu hình được, các đối tượng, đường lưới và viền ô có công tắc độc lập, nền có thể là một màu hoặc trong suốt, và việc ghi tệp đi qua một phép replace cùng thư mục nguyên tử giữ nguyên mục tiêu hiện có nếu có gì đó thất bại
Lý do thứ này cần một exporter riêng thay vì một cờ trên con đường in là phân trang không phải một tầng tùy chọn mà bạn có thể tắt. Nó chính là thứ mà pipeline trang tồn tại để làm
Vì sao không kết xuất vùng qua pipeline in?
Vì pipeline in chèn một trang giữa bạn và các ô. Cỡ giấy quyết định bao nhiêu vừa vặn, lề đẩy nội dung vào trong, đầu và chân trang chiếm các dải mà bạn không hề xin, tiêu đề in lặp lại các hàng mà bạn đã có, và ngắt trang xẻ đôi vùng. Một khối tóm tắt tình cờ vắt qua một điểm ngắt ra thành hai bức ảnh với hàng thú vị bị cắt làm đôi. Bạn có thể bù tất cả điều đó bằng cách dựng một cỡ trang tùy biến khớp chính xác vùng, và mọi người có làm vậy, nhưng điều đó nghĩa là tính lại hình học giấy mỗi khi vùng thay đổi và vẫn để dải đầu trang cùng logic tiêu đề in nằm trên đường
Exporter ô đo hình chữ nhật, cấp phát một bitmap đúng kích thước đó, vẽ các ô vào nó, và mã hóa. Chẳng có trang nào, nên chẳng có gì để cấu hình mà bỏ đi. Với các trường hợp bạn thực sự muốn giấy, con đường xuất PDF là công cụ đúng và được đề cập trong bài viết về xuất PDF bảng tính
Đo trước khi kết xuất
Measure trả về các kích thước pixel mà cài đặt hiện tại sẽ tạo ra mà không mã hóa gì. Điều đó quan trọng vì hai lý do. Một mẫu HTML hay email thường cần kích thước ảnh trước khi ảnh tồn tại, để dành chỗ hộp và tránh dịch chuyển bố cục. Và một dịch vụ kết xuất các vùng do người dùng chọn cần một cách để từ chối một yêu cầu phi lý trước khi cấp phát cho nó
uses
lxHandleX, lxPagination;
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Exporter: TXLSCellImageExporter;
Summary: TXLSXRange;
W, H, Bytes: Integer;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('quarter.xlsx');
Sheet := Book.Sheets.ByPos[0];
Summary := Sheet.Range['A1:F20'];
Exporter := TXLSCellImageExporter.Create;
try
Exporter.ImageFormat := xpifPng; // PNG giữ các nét mảnh sắc nét
Exporter.DPI := 96;
Exporter.Scale := 2.0; // đầu ra mật độ retina
Exporter.IncludeGridlines := False;
Exporter.IncludeCellBorders := True;
Exporter.TransparentBackground := True;
Exporter.MaxPixels := 40 * 1000 * 1000;
Exporter.MaxBytes := 8 * 1024 * 1024;
if not Exporter.Measure(Summary, W, H) then
raise Exception.Create('range exceeds the configured budget');
// W và H giờ đã biết; dành hộp bố cục trước khi mã hóa
Bytes := Exporter.Save(Summary, 'summary.png');
if Bytes <= 0 then
raise Exception.Create('image export failed, previous file kept');
finally
Exporter.Free;
end;
finally
Book.Free;
end;
end;
Ngân sách, vì tỉ lệ nhân lên
MaxPixels và MaxBytes không phải trang trí phòng thủ. Số pixel tăng theo bình phương hệ số tỉ lệ và theo bình phương tỉ số độ phân giải, nên một vùng hợp lý 1200 nhân 800 ở 96 DPI trở thành xấp xỉ 47 megapixel ở 600 DPI, và một người dùng chọn cả vùng sử dụng thay vì một khối tóm tắt cộng thêm một bậc độ lớn nữa lên trên. Không có trần, dạng thất bại là một lần cấp phát mà tiến trình không thể đáp ứng, thứ kéo sập mọi thứ khác mà tiến trình đó đang làm
Có trần, yêu cầu thất bại và caller được lựa chọn: từ chối, giảm tỉ lệ, hay thu hẹp vùng. Đó là một vị trí tốt hơn nhiều cho một máy chủ báo cáo, và đó là cùng lý lẽ đằng sau các ngân sách tường minh trong bộ giải mã metafile được mô tả trong bài viết về bộ giải mã EMF và WMF có biên
Phép replace nguyên tử, và vì sao thư mục quan trọng
Save vào một tên tệp không ghi vào mục tiêu. Nó ghi một tệp tạm trong cùng thư mục, mã hóa vào đó, và chỉ sau đó mới replace mục tiêu. Nếu mã hóa thất bại, nếu ngân sách bị vượt giữa chừng, hay nếu tiến trình bị giết, ảnh trước đó vẫn ở đó và vẫn hợp lệ. Một dashboard tái sinh các ô của nó theo lịch vì vậy chưa từng hiện một PNG bị cụt, triệu chứng quen thuộc của một phép ghi ngây thơ mở đích và bắt đầu chảy dữ liệu
Chi tiết cùng thư mục không phải ngẫu nhiên. Một replace nguyên tử chỉ nguyên tử trong một volume, vì giữa các volume hệ điều hành phải sao chép rồi xóa, điều tái giới thiệu đúng khung thời gian bạn đang cố đóng. Bất kỳ hiện thực nào của mẫu hình này đặt tệp tạm vào thư mục temp hệ thống đều không nguyên tử trên một máy mà đầu ra nằm trên một ổ khác
Các sự kiện paint vẽ trên canvas thật
Cả exporter vùng lẫn exporter trang đều phơi các sự kiện paint đầu và đuôi, và chúng nhận một ngữ cảnh chỉ đọc đầy đủ thay vì chỉ một handle canvas. TXLSPagePaintContext mang canvas sống, các biên pixel, cỡ trang theo điểm, độ phân giải và tỉ lệ thực sự đang dùng, số trang tài liệu, số trang trong bảng, tổng số trang, tên bảng, và bảng tính nguồn gốc theo cả hương vị cổ điển lẫn XLSX. Đủ để vẽ một watermark co giãn đúng, hay một con dấu trang biết mình đang ở đâu trong lượt chạy
procedure TReportJob.StampDraft(Sender: TObject;
const AContext: TXLSPagePaintContext);
begin
// Nhận biết tỉ lệ, nên con dấu nhìn giống nhau ở 1x và 3x
AContext.Canvas.Font.Height := Round(-48 * AContext.Scale);
AContext.Canvas.Font.Color := clSilver;
AContext.Canvas.Brush.Style := bsClear;
AContext.Canvas.TextOut(AContext.Bounds.Left + Round(24 * AContext.Scale),
AContext.Bounds.Top + Round(24 * AContext.Scale), 'DRAFT');
end;
Exporter.AfterPaint := Job.StampDraft;
Ba hành vi đáng để dựa vào. Các sự kiện bắn đúng một lần cho mỗi khung được kết xuất, gồm cả mỗi khung của một TIFF nhiều trang, nên một bộ đếm tăng trong handler đáng tin. Chúng giữ im lặng trong lúc đo, nên một handler có tác dụng phụ không chạy hai lần cho một đầu ra. Và nếu sự kiện đầu ném ngoại lệ, sự kiện đuôi không bắn và chẳng byte ảnh một phần nào được ghi, nên một ngoại lệ trong mã vẽ của bạn không thể tạo ra một tệp bị đóng dấu một nửa
Chọn định dạng
PNG cho mọi thứ giàu văn bản. JPEG áp dụng một phép biến đổi khối tạo ra tiếng vọng nhìn thấy được quanh các nét mảnh tương phản cao, và viền ô cùng văn bản nhỏ chính là những thứ đó, còn các lỗi nén sống sót ở những cài đặt chất lượng mà một bức ảnh trông hoàn hảo. JPEG giành được chỗ của mình khi vùng bị chi phối bởi các ảnh nhúng và kích thước tệp quan trọng hơn độ trung thực cạnh. Nền trong suốt đòi PNG, vì JPEG không có kênh alpha, nên một ô định nằm trên một bề mặt có màu đã chọn thay bạn
Nếu vùng của bạn chứa các ô gộp, hãy kiểm đầu ra đối chiếu với bảng: các vùng gộp tương tác với bề rộng cột theo những cách khiến người ta ngạc nhiên, và các quy tắc bố cục được đề cập trong bài viết về ô gộp và mẫu báo cáo. HotXLS đọc và ghi XLS, XLSX, ODS và CSV từ Delphi và C++Builder mà không phụ thuộc Excel, và toàn bộ bề mặt exporter được ghi tài liệu trên trang sản phẩm HotXLS Delphi spreadsheet component