HotXLS สร้าง Excel camera object บนเวิร์กชีต XLSX จาก Delphi ผ่าน AddCamera camera object คือรูปภาพที่เชื่อมโยงถาวรกับช่วงเซลล์หนึ่ง Excel เรนเดอร์มันใหม่จากช่วงต้นทางทุกครั้งที่เปิดสมุดงานหรือเมื่อต้นทางเปลี่ยนแปลง ดังนั้นแดชบอร์ดจึงแสดงมุมมองสดของตารางที่อยู่บนชีตอื่นได้ ที่ขนาดใดก็ตาม หมุนได้ถ้าต้องการ
ฟีเจอร์นี้มีอยู่ใน Excel ในชื่อเครื่องมือ Camera ปุ่มที่ผู้ใช้ส่วนใหญ่ไม่เคยเห็นเพราะไม่ได้อยู่บน ribbon โดยปริยาย มันแก้ปัญหาแดชบอร์ดจริงได้ดีกว่าทางเลือกอื่น ๆ ช่วงที่คัดลอกมาจะล้าสมัย กราฟไม่สามารถแสดงเนื้อหาเซลล์ตามอำเภอใจได้ และรูปภาพที่เชื่อมโยงแบบวางด้วยมือไม่สามารถสร้างขึ้นด้วยโค้ดได้ camera object คือโครงสร้างเดียวที่ทั้งสดและตามอำเภอใจได้พร้อมกัน
สิ่งนี้ถูกบันทึกไว้ที่ไหน และทำไมถึงสำคัญ
สเปกสเปรดชีตหลักไม่ได้อธิบาย camera object ไว้ มันถูกปฏิบัติเป็นรายละเอียดการอิมพลีเมนต์ คำอธิบายที่เป็นทางการอยู่ในเอกสาร drawing-markup ภายใต้หัวข้อ Camera Tool และการรู้จุดนี้ช่วยประหยัดเวลาค้นหาเอกสารผิดไปได้ครึ่งวัน
ในเชิงโครงสร้าง camera object คือ picture element ธรรมดาที่คุณสมบัติ non-visual picture มี extension list extension นี้ระบุด้วย GUID คงที่ และภายในมีอิลิเมนต์จาก namespace drawing ปี 2010 ที่บันทึกสองสิ่ง คือช่วงต้นทางเป็นการอ้างอิงแบบสัมบูรณ์สไตล์ A1 ระบุชีตได้ถ้าต้องการ และตัวระบุ shape ทุกอย่างอื่นในรูปภาพเป็นแบบปกติ
การสร้างมันขึ้นมา
มี overload สองแบบเพราะมีสองวิธีที่สะดวกในการระบุชื่อช่วง รูปแบบข้อความรับการอ้างอิงตามที่จะถูกเก็บไว้เป๊ะ ซึ่งเป็นสิ่งที่คุณต้องการสำหรับต้นทางข้ามชีต รูปแบบพิกัดรับพิกัดเซลล์สี่ค่าบนชีตเดียวกันและสร้างการอ้างอิงแบบสัมบูรณ์ให้คุณ
uses
lxHandleX;
var
Book: TXLSXWorkbook;
Dashboard: TXLSXWorksheet;
Cam: TXLSXImage;
begin
Book := TXLSXWorkbook.Create;
try
if Book.Open('reporting.xlsx') <> 1 then
Exit;
Dashboard := Book.Sheets[0];
// มุมมองสดของ Data!$B$2:$D$4 วางทับ B10:F20 บนแดชบอร์ด
Cam := Dashboard.AddCamera('Data!$B$2:$D$4', 10, 2, 20, 6);
// กรอบวางตำแหน่งเป็นค่าเริ่มต้นของ Excel เองที่คอลัมน์ 64 px และ
// แถว 20 px ปรับขนาดที่วาดเป็นหน่วย EMU ภายหลังถ้าจำเป็น
Cam.WidthEMU := Round(12.5 * 914400 / 2.54); // 12.5 ซม.
Cam.HeightEMU := Round(6.0 * 914400 / 2.54);
Book.SaveAs('reporting-dashboard.xlsx');
finally
Book.Free;
end;
end;
อ็อบเจกต์ที่คืนกลับมาคืออ็อบเจกต์รูปภาพปกติที่มีคุณสมบัติพิเศษเพิ่มหนึ่งอย่างคือ CameraRange ซึ่งไม่ว่างเมื่อรูปภาพนั้นเป็น camera พอดี นี่คือวิธีที่คุณตรวจจับ camera ในสมุดงานที่คุณไม่ได้สร้างเองด้วย คือเดินผ่านรูปภาพและตรวจคุณสมบัตินี้
เหตุใดรูปภาพสำรองจึงไม่ต้องเป็นของจริง
ทุกรูปภาพในแพ็กเกจ XLSX ต้องการ image part หนึ่งชิ้น และ camera object ก็ไม่มีข้อยกเว้น แต่ Excel เพิกเฉยต่อรูปภาพนั้น เมื่อโหลด มันจะเรนเดอร์ช่วงที่เชื่อมโยงใหม่และวาดผลลัพธ์ ไบต์ที่ฝังอยู่มีไว้เพียงเพื่อเป็นแคชการแสดงผลสำหรับเครื่องมือที่ไม่ได้อิมพลีเมนต์พฤติกรรมของ camera
ข้อเท็จจริงนี้ตัดระบบย่อยทั้งระบบออกจากการอิมพลีเมนต์ ไม่จำเป็นต้องแรสเตอร์ช่วงต้นทาง ไม่จำเป็นต้องมีเอนจินเรนเดอร์เพื่อสร้างสแนปช็อต และไม่มีความเสี่ยงที่ภาพที่แคชไว้จะไม่ตรงกับภาพสดใน Excel HotXLS เขียน metafile สำรองแบบเล็กที่สุด คือ header record หนึ่งชุดและ end-of-file record หนึ่งชุด รวม 108 ไบต์ ซึ่งทำให้โครงสร้างของแพ็กเกจสมบูรณ์และไม่มีต้นทุนอะไรเลย
ผลที่ต้องวางแผนไว้อย่างหนึ่งคือ ตัวแสดงผลที่เรนเดอร์ XLSX โดยไม่อิมพลีเมนต์ camera object จะแสดงรูปสำรอง ซึ่งเป็นภาพว่างเปล่า หากสมุดงานของคุณถูกใช้งานโดยเครื่องมือแบบนั้น camera object เป็นโครงสร้างที่ผิดตัวเลือก และภาพที่เรนเดอร์ของช่วงนั้นคือตัวเลือกที่ถูกต้อง
การแปลงหน่วยที่ผิดพลาดได้ง่าย
เรขาคณิตของการวาดใน Open XML วัดเป็น English Metric Unit โดยหนึ่งนิ้วเท่ากับ 914,400 EMU และหนึ่งเซนติเมตรเท่ากับ 360,000 อย่างไรก็ตาม header ของ metafile บันทึกกรอบของมันเป็นหน่วย 0.01 มิลลิเมตร การแปลงระหว่างสองหน่วยนี้คือการหารด้วย 360
คุ้มค่าที่จะระบุจุดนี้ไว้เพราะข้อผิดพลาดนี้เงียบมาก การแปลงผ่านพิกเซลที่ 96 DPI แทน คือคูณด้วย 2540 แล้วหารด้วย 9525 จะให้ค่าที่ใหญ่เกินไป 96 เท่า และไม่มีอะไรปฏิเสธมัน แพ็กเกจนั้นถูกต้อง รูปภาพถูกวางตำแหน่งถูกต้องโดย anchor และมีเพียงกรอบที่ประกาศไว้ของ metafile เท่านั้นที่ไร้ความหมาย โมเดล EMU และพฤติกรรมการปัดเศษของมันอธิบายไว้ใน เรขาคณิตของรูปภาพ หน่วย EMU และการปรับขนาด
การเปิด-บันทึกซ้ำสมุดงานที่มี camera อยู่แล้ว
การเปิดแล้วบันทึกสมุดงานจะรักษา camera object ไว้ รวมทั้ง extension element และการอ้างอิงช่วงของมัน สิ่งนี้สำคัญกว่าการสร้างมันขึ้นมาใหม่ สมุดงานส่วนใหญ่ที่มี camera object ถูกสร้างขึ้นใน Excel โดยนักวิเคราะห์ และไลบรารีที่แปลงมันเป็นรูปภาพธรรมดาอย่างเงียบ ๆ ตอนบันทึกจะทำลายพฤติกรรมสดที่นักวิเคราะห์พึ่งพาไว้
// ตรวจสอบว่ารูปภาพใดเป็น camera และชี้ไปที่ไหน
for I := 0 to Sheet.Images.Count - 1 do
if Sheet.Images[I].CameraRange <> '' then
Writeln(Format('camera %d -> %s',
[I, Sheet.Images[I].CameraRange]));
เมื่อคุณสร้างแดชบอร์ดด้วยโปรแกรม การตรวจสอบนี้ก็เป็นการทดสอบ regression ด้วย หลังจากรอบบันทึกแล้วเปิดใหม่ จำนวน camera ต้องเท่าเดิมและชี้ไปยังช่วงเดิม การจัดการรูปภาพและ drawing ทั่วไป รวมถึงโมเดล anchor ที่กำหนดตำแหน่งของมัน อธิบายไว้ใน กราฟ รูปภาพ และ drawing
เมื่อไหร่ camera ดีกว่าทางเลือกอื่น
ใช้ camera object เมื่อตารางสดเดียวกันต้องปรากฏบนหลายชีตในขนาดต่างกัน เมื่อ layout สำหรับพิมพ์ต้องการพื้นที่จากชีตหนึ่งประกอบร่วมกับพื้นที่จากชีตอื่น หรือเมื่อบล็อกสรุปควรตามการแก้ไขที่เกิดขึ้นที่อื่นโดยไม่ต้องมีสูตรเชื่อมทุกเซลล์ทีละเซลล์
ให้เลือกสูตรธรรมดาเมื่อเป้าหมายเป็นเพียงไม่กี่เซลล์ เพราะสูตรข้ามชีตเรียบง่ายกว่าและทุกเครื่องมือเข้าใจมัน ให้เลือกกราฟเมื่อข้อมูลเป็นชุดข้อมูลจริง ๆ ไม่ใช่บล็อกที่จัดรูปแบบ และให้เลือกภาพที่เรนเดอร์แล้วเมื่อสมุดงานจะถูกใช้งานโดยเครื่องมืออื่นนอกจาก Excel หรือเมื่อสแนปช็อตต้องไม่เปลี่ยนหลังจากส่งมอบ รายงานที่จัดเก็บถาวรไม่ควรเป็นแบบสด
ข้อสังเกตเรื่อง layout หนึ่งข้อจากประสบการณ์จริง camera แสดงช่วงต้นทางตรงตามที่จัดรูปแบบไว้ทุกประการ รวมทั้งเซลล์ที่ผสาน conditional format และความกว้างคอลัมน์ การได้แดชบอร์ดที่ดูสะอาดจึงเริ่มจากการจัดรูปแบบช่วงต้นทางราวกับว่ามันคือเอาต์พุตสุดท้าย ซึ่งเป็นวินัยเดียวกับที่อธิบายไว้ใน เซลล์ที่ผสานและ layout เทมเพลตรายงาน
Camera object, drawing และตัวเขียนแพ็กเกจ XLSX ที่อยู่เบื้องหลังล้วนอยู่ในไลบรารีเดียวสำหรับ Delphi และ C++Builder รายการฟีเจอร์ฉบับเต็มอยู่ที่หน้า HotXLS Delphi spreadsheet component