/// <summary> /// Draws the used devices section to the file. /// </summary> /// <param name="file">The file that is drawn to.</param> /// <param name="dlr">The report being drawn.</param> /// <param name="row">The x coordinate to start drawing the section in cells.</param> /// <param name="col">The y coordinate to start drawing the section in cells.</param> /// <returns>A Tuple contining the width and height respectively of the drawn section.</returns> protected Tuple <int, int> DrawUsedDevices(XlsFile file, DataLogReport dlr, int row, int col) { var l = dlr.localization; // Draw the header file.SetCellValue(row, col, l.serialNumber, sectionHeaderFormat); file.SetCellValue(row, col + 1, l.name, sectionHeaderFormat); file.SetCellValue(row, col + 2, l.certificationDate, sectionHeaderFormat); file.SetCellValue(row, col + 3, l.deviceModel, sectionHeaderFormat); // Draw the content var offset = 1; foreach (var device in dlr.devices) { var rowoff = row + offset; file.SetCellValue(rowoff, col, device.serialNumber, sectionContentFormat); file.SetCellValue(rowoff, col + 1, device.name, sectionContentFormat); file.SetCellValue(rowoff, col + 2, GetDeviceCalibrationTime(device), sectionContentFormat); file.SetCellValue(rowoff, col + 3, l.GetDeviceModelString(device.serialNumber.deviceModel), sectionContentFormat); offset++; } return(new Tuple <int, int>(4, offset)); }
/// <summary> /// Draws the reports device measurement statistics to the file. /// </summary> /// <returns>A Tuple containing the width and height respectively of the drawn section.</returns> /// <param name="file">The file that is drawn to.</param> /// <param name="dlr">The report being drawn.</param> /// <param name="row">The x coordinate to start drawing the section in cells.</param> /// <param name="col">The y coordinate to start drawing the section in cells.</param> protected Tuple <int, int> DrawDeviceAverages(XlsFile file, DataLogReport dlr, int row, int col) { var l = dlr.localization; // Draw header file.SetCellValue(row, col, l.serialNumber, sectionHeaderFormat); file.SetCellValue(row, col + 1, l.minimum, sectionHeaderFormat); file.SetCellValue(row, col + 2, l.maximum, sectionHeaderFormat); file.SetCellValue(row, col + 3, l.average, sectionHeaderFormat); // Draw the content var offset = 1; foreach (var pair in dlr.dataLogResults) { var ro = row + offset++; var sensorType = pair.Key.type; var u = ion.preferences.units.DefaultUnitFor(sensorType); var min = pair.Value.minimum.ConvertTo(u); var max = pair.Value.maximum.ConvertTo(u); var avg = pair.Value.average.ConvertTo(u); file.SetCellValue(ro, col, pair.Key.device.serialNumber, sectionContentFormat); file.SetCellValue(ro, col + 1, SensorUtils.ToFormattedString(min, true), sectionContentFormat); file.SetCellValue(ro, col + 2, SensorUtils.ToFormattedString(max, true), sectionContentFormat); file.SetCellValue(ro, col + 3, SensorUtils.ToFormattedString(avg, true), sectionContentFormat); } return(new Tuple <int, int>(4, offset)); }
public override Task <bool> Export(Stream stream, DataLogReport dlr) { return(Task.Factory.StartNew(() => { try { // TODO [email protected]: Not necessary var scaleReduction = 60; // TODO DEFINE var file = new XlsFile((showAllData ? 2 : 1) + dlr.graphImages.Count, TExcelFileFormat.v2013, true); file.AllowOverwritingFiles = true; file.PrintScale = scaleReduction; // Note: [email protected]: Per kyle's original writing // SET A UNIFORM CELL WIDTH FOR COVER PAGE ITEMS. DEFAULT COLUMN WIDTH = 3189 AND SETTING IT TO 1.3x RESULTING IN 4317 file.SetColWidth(1, 8, 4317); // TODO DEFINE InitializeToFile(file); RenderFile(file, dlr); // Commit file to stream using (var pdf = new FlexCelPdfExport(file, true)) { pdf.GetFontData += (sender, e) => { var ms = new MemoryStream(1024 * 64); using (var fontStream = dlr.localization.GetFontStream()) { var buffer = new byte[1024]; var read = -1; while ((read = fontStream.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, buffer.Length); } } e.FontData = ms.ToArray(); ms.Dispose(); }; pdf.BeginExport(stream); for (int i = 1; i <= file.SheetCount; i++) { file.ActiveSheet = i; pdf.ExportSheet(); } pdf.EndExport(); } return true; } catch (Exception e) { Log.E(this, "Failed to export datalog report", e); return false; } })); }
/// <summary> /// Draws the graphs for each of the devices. /// </summary> /// <returns>The graphs.</returns> /// <param name="file">File.</param> /// <param name="dlr">Dlr.</param> /// <param name="row">The x coordinate.</param> /// <param name="col">The y coordinate.</param> private Tuple <int, int> DrawGraphs(XlsFile file, DataLogReport dlr, int row, int col) { var l = dlr.localization; var imageCellWidth = 8; var imageCellHeight = 4; var index = 0; foreach (var sensor in dlr.dataLogResults.Keys) { if (!dlr.graphImages.ContainsKey(sensor)) { Log.E(this, "Failed to export sensor graph"); continue; } int xoff = 0, yoff = 0; if (index > 0) { xoff = 1; yoff = 1; } else { xoff = col; yoff = row; } var image = dlr.graphImages[sensor]; file.MergeCells(yoff, xoff, yoff + imageCellHeight, xoff + imageCellWidth); file.SetRowHeight(yoff, (int)(image.height * FlxConsts.RowMult)); TClientAnchor anchor = new TClientAnchor(TFlxAnchorType.MoveAndDontResize, yoff, 0, xoff, 0, yoff + imageCellHeight, 0, xoff + imageCellWidth, 0); double width = 0.0, height = 0.0; anchor.CalcImageCoords(ref height, ref width, file); // Width should always be greater than the height. anchor = new TClientAnchor(TFlxAnchorType.MoveAndDontResize, yoff, 0, xoff, 0, (int)height, (int)width, file); var imageProperties = new TImageProperties(); imageProperties.Anchor = anchor; file.AddImage(image.data, TXlsImgType.Png, imageProperties); index++; file.ActiveSheet++; } return(new Tuple <int, int>(imageCellWidth, index * (imageCellHeight + 1))); }
/// <summary> /// Draws all of the sections into the file. /// </summary> /// <param name="file">File.</param> /// <param name="dlr">Dlr.</param> private void RenderFile(XlsFile file, DataLogReport dlr) { // Cell coordinates var row = 1; Tuple <int, int> size; file.ActiveSheet = 1; //////////// // SHEET 1 //////////// // Draw the report header size = DrawAppionLogo(file, dlr); row += size.Item2; row += 2; // Draw the used devices section size = DrawUsedDevices(file, dlr, row, 1); row += size.Item2; row += 2; // Draw the date section size = DrawReportDates(file, dlr, row, 1); row += size.Item2; row += 2; // Draw the device averages size = DrawDeviceAverages(file, dlr, row, 1); row += size.Item2; row += 2; // Draw the graph content size = DrawGraphs(file, dlr, row, 1); row += size.Item2; row += 2; //////////// // SHEET 2 //////////// row = 1; // Draw raw data if (showAllData) { file.ActiveSheet++;; size = DrawAllMeasurements(file, dlr, row, 1); } }
public override Task <bool> Export(Stream stream, DataLogReport dlr) { return(Task.Factory.StartNew(() => { try { var file = new XlsFile(1, TExcelFileFormat.v2013, true); InitializeToFile(file); RenderFile(file, dlr); file.Save(stream, TFileFormats.Text, '|', Encoding.UTF8); return true; } catch (Exception e) { Log.E(this, "Failed to export CSV report", e); return false; } })); }
public override Task <bool> Export(Stream stream, DataLogReport dlr) { return(Task.Factory.StartNew(() => { try { var file = new XlsFile(2, TExcelFileFormat.v2013, true); file.AllowOverwritingFiles = true; InitializeToFile(file); RenderFile(file, dlr); file.Save(stream); return true; } catch (Exception e) { Log.E(this, "Failed to export excel report", e); return false; } })); }
/// <summary> /// Draws the important dates for the report. /// </summary> /// <returns>The report dates.</returns> /// <param name="file">The file that is drawn to.</param> /// <param name="dlr">The report being drawn.</param> /// <param name="row">The x coordinate to start drawing the section in cells.</param> /// <param name="col">The y coordinate to start drawing the section in cells.</param> protected Tuple <int, int> DrawReportDates(XlsFile file, DataLogReport dlr, int row, int col) { var l = dlr.localization; // Draw the header // Merge the header cells file.MergeCells(row, col + 1, row, col + 3); file.MergeCells(row + 1, col + 1, row + 1, col + 3); // Set the cell format for the merged cells (without this the merged cell doesn't have a format and is white) for (int i = 1; i < 4; i++) { file.SetCellFormat(row, col + i, sectionContentFormat); } file.SetCellValue(row, col, l.reportCreated, sectionHeaderFormat); file.SetCellValue(row, col + 1, DateTime.Now.ToLongDateString(), sectionContentFormat); file.SetCellValue(row + 1, col, l.reportDates, sectionHeaderFormat); file.SetCellValue(row + 1, col + 1, "", sectionHeaderFormat); var startEnds = dlr.GatherSessionStartEnds(); var times = new List <Tuple <DateTime, DateTime> >(startEnds.Values); times.Sort(); var offset = 2; // Draw the dates foreach (var time in times) { var ro = row + offset++; // row offset; file.MergeCells(ro, col, ro, col + 3); file.SetCellValue(ro, col, time.Item1.ToShortDateString() + " " + time.Item1.ToShortTimeString() + " - " + time.Item2.ToShortDateString() + " " + time.Item2.ToShortTimeString(), sectionContentFormat); // Set the cell format for the merged cells (without this the merged cell doesn't have a format and is white) for (int i = 0; i < 4; i++) { file.SetCellFormat(ro, col + i, sectionContentFormat); } } return(new Tuple <int, int>(2, offset)); }
/// <summary> /// Attempts to draw the Appion logo into the upper left of the file on the current sheet. /// </summary> /// <param name="file">File.</param> /// <returns>A Tuple containing the width and height respectively of the drawn section.</returns> private Tuple <int, int> DrawAppionLogo(XlsFile file, DataLogReport dlr) { if (dlr.appionLogoPng != null) { // Add the image var image = new TImageProperties(); image.Anchor = new TClientAnchor(TFlxAnchorType.MoveAndDontResize, 1, 0, 1, 0, 5, 255, 3, 1024); image.ShapeName = "Logo"; file.AddImage(dlr.appionLogoPng.data, image); // Add the header file.MergeCells(4, 4, 5, 6); file.SetCellValue(4, 4, dlr.reportName, titleFormat); return(new Tuple <int, int>(6, 4)); } else { Log.E(this, "Failed to draw appion logo: no bitmap bytes"); return(new Tuple <int, int>(0, 0)); } }
/// <summary> /// Draws the graphs for each of the devices. /// </summary> /// <returns>The graphs.</returns> /// <param name="file">File.</param> /// <param name="dlr">Dlr.</param> /// <param name="row">The x coordinate.</param> /// <param name="col">The y coordinate.</param> private Tuple <int, int> DrawSmallGraphs(XlsFile file, DataLogReport dlr, int row, int col) { var l = dlr.localization; var imageCellWidth = 4; var imageCellHeight = 3; var index = 0; foreach (var sensor in dlr.dataLogResults.Keys) { if (!dlr.graphImages.ContainsKey(sensor)) { Log.E(this, "Failed to export sensor graph"); continue; } int xoff = 0, yoff = 0; // The shift that is used to stagger the graphs down the pages. xoff = col + (index % 2 == 1 ? imageCellWidth + 1 : 0); yoff = (int)(row + (index / 2 * imageCellHeight)); var image = dlr.graphImages[sensor]; file.MergeCells(yoff, xoff, yoff + imageCellHeight, xoff + imageCellWidth); file.SetRowHeight(yoff, (int)(image.height * FlxConsts.RowMult)); TClientAnchor anchor = new TClientAnchor(TFlxAnchorType.MoveAndDontResize, yoff, 0, xoff, 0, yoff + imageCellHeight, 0, xoff + imageCellWidth, 0); double width = 0.0, height = 0.0; anchor.CalcImageCoords(ref height, ref width, file); // Width should always be greater than the height. anchor = new TClientAnchor(TFlxAnchorType.MoveAndDontResize, yoff, 0, xoff, 0, (int)height, (int)width, file); var imageProperties = new TImageProperties(); imageProperties.Anchor = anchor; file.AddImage(image.data, TXlsImgType.Png, imageProperties); index++; } return(new Tuple <int, int>((imageCellWidth + 1) * 2, (int)Math.Ceiling(index / 2.0) * (imageCellHeight + 1))); }
/// <summary> /// Draws all of the sections into the file. /// </summary> /// <param name="file">File.</param> /// <param name="dlr">Dlr.</param> private void RenderFile(XlsFile file, DataLogReport dlr) { // Cell coordinates var row = 1; Tuple <int, int> size; file.ActiveSheet = 1; //////////// // SHEET 1 //////////// // Draw the used devices section size = DrawUsedDevices(file, dlr, row, 1); row += size.Item2; row += 2; // Draw the date section size = DrawReportDates(file, dlr, row, 1); row += size.Item2; row += 2; // Draw the device averages size = DrawDeviceAverages(file, dlr, row, 1); row += size.Item2; row += 2; file.AutofitCol(1, size.Item1, false, 1); //////////// // SHEET 2 //////////// row = 1; // Draw raw data file.ActiveSheet = 2; size = DrawAllMeasurements(file, dlr, row, 1); }
/// <summary> /// Draws the content of the csv. /// </summary> /// <param name="file">File.</param> /// <param name="dlr">Dlr.</param> private void RenderFile(XlsFile file, DataLogReport dlr) { DrawAllMeasurements(file, dlr, 1, 1); }
// Implemented for IDataLogExporter public abstract Task <bool> Export(Stream stream, DataLogReport dlr);
/// <summary> /// Draws all of the session's sensor measurement data. This is done in a fairly simple, yet tedious way. Across /// the section header, we will list all of the sensors in the report. The left-most column will show all of the /// sorted dates in all of the sessions. Then, for each sensor, it will list all of its session measurements. When /// a session is complete, we will the bottom of that session's measurement column with a red border. /// </summary> /// <returns>The all measurements.</returns> /// <param name="file">File.</param> /// <param name="dlr">Dlr.</param> /// <param name="row">The x coordinate.</param> /// <param name="col">The y coordinate.</param> protected Tuple <int, int> DrawAllMeasurements(XlsFile file, DataLogReport dlr, int row, int col) { var l = dlr.localization; var sensors = dlr.dataLogResults.Keys; // Coallate data var unsortedMasterDates = new HashSet <DateTime>(); var masterDates = new List <DateTime>(); var sessionBreaks = new Dictionary <int, DateTime>(); var measurements = new Dictionary <GaugeDeviceSensor, Measurements>(); foreach (var sdlr in dlr.dataLogResults) { foreach (var sid in sdlr.Value.sessionIds) { Measurements m; if (!measurements.TryGetValue(sdlr.Key, out m)) { measurements[sdlr.Key] = m = new Measurements() { sensor = sdlr.Key, measurements = new Dictionary <DateTime, Scalar>(), }; } foreach (var dlm in sdlr.Value[sid]) { m.measurements[dlm.recordedDate] = dlm.measurement; unsortedMasterDates.Add(dlm.recordedDate); } var last = sdlr.Value[sid][sdlr.Value[sid].Count - 1].recordedDate; if (sessionBreaks.ContainsKey(sid)) { var dt = sessionBreaks[sid]; if (last > dt) { sessionBreaks[sid] = last; } } else { sessionBreaks[sid] = last; } } } masterDates.AddRange(unsortedMasterDates); masterDates.Sort(); // Draw Header Padding file.SetCellValue(row, col, "", sectionHeaderFormat); var hi = 1; foreach (var key in measurements.Keys) { file.SetCellValue(row, col + hi++, GetHeaderStringFromSensor(ion, measurements[key].sensor), sectionHeaderFormat); } // Draw the master dates list to the file. for (int i = 0; i < masterDates.Count; i++) { var date = masterDates[i]; var format = sessionBreaks.ContainsValue(date) ? sessionBreakFormat : sectionContentFormat; file.SetCellValue(row + i + 1, col, date.ToShortDateString() + " " + date.ToLongTimeString(), format); } // Draw the content for the measurements var mi = 1; foreach (var m in measurements) { for (int y = 0; y < masterDates.Count; y++) { var dt = masterDates[y]; if (m.Value.measurements.ContainsKey(dt)) { var scalar = ion.preferences.units.ToDefaultUnit(m.Value.measurements[dt]); var format = sessionBreaks.ContainsValue(dt) ? sessionBreakFormat : sectionContentFormat; file.SetCellValue(row + y + 1, row + mi, SensorUtils.ToFormattedString(scalar), format); } } mi++; } file.AutofitCol(col, col + mi, false, 1.0); return(new Tuple <int, int>(1 + mi, 1 + measurements.Count)); }