147 lines
5.3 KiB
C#
147 lines
5.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using NPOI.SS.UserModel;
|
|
using NPOI.XSSF.UserModel;
|
|
using OpenCvSharp;
|
|
|
|
namespace ExcelImageHelper
|
|
{
|
|
public class ExcelEntry
|
|
{
|
|
public string Name { get; set; } = "";
|
|
public Mat Image { get; set; }
|
|
public List<List<string>> ParametersSets { get; set; } = new List<List<string>>();
|
|
public string Content { get; set; } = "";
|
|
}
|
|
|
|
public class ExcelImageInserter
|
|
{
|
|
private IWorkbook workbook;
|
|
private string filePath;
|
|
private int jpgQuality;
|
|
|
|
// 생성자: JPEG 품질 지정 (0~100, 기본 95)
|
|
public ExcelImageInserter(string excelPath, int jpegQuality = 95)
|
|
{
|
|
filePath = excelPath;
|
|
// Math.Clamp 대신 삼항연산으로 제한
|
|
jpgQuality = (jpegQuality < 0) ? 0 : (jpegQuality > 100 ? 100 : jpegQuality);
|
|
|
|
// 폴더 존재 확인 후 없으면 생성
|
|
string folderPath = Path.GetDirectoryName(filePath);
|
|
if (!Directory.Exists(folderPath))
|
|
{
|
|
Directory.CreateDirectory(folderPath);
|
|
}
|
|
|
|
// 파일이 있으면 열고, 없으면 새로 생성
|
|
if (File.Exists(filePath))
|
|
{
|
|
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
|
{
|
|
workbook = new XSSFWorkbook(fs);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
workbook = new XSSFWorkbook();
|
|
}
|
|
}
|
|
|
|
// 단일 Entry 추가
|
|
public void AddEntry(ExcelEntry entry, string sheetName, double widthCm, double heightCm)
|
|
{
|
|
ISheet sheet = workbook.GetSheet(sheetName) ?? workbook.CreateSheet(sheetName);
|
|
|
|
int startRow = 0;
|
|
int startCol = 0;
|
|
|
|
// Name 삽입
|
|
IRow nameRow = sheet.GetRow(startRow) ?? sheet.CreateRow(startRow);
|
|
ICell nameCell = nameRow.GetCell(startCol) ?? nameRow.CreateCell(startCol);
|
|
nameCell.SetCellValue(entry.Name);
|
|
|
|
// 이미지 삽입
|
|
int imageRowStart = startRow + 1;
|
|
|
|
// JPEG 인코딩 시 설정한 품질 적용
|
|
var jpgParams = new ImageEncodingParam[]
|
|
{
|
|
new ImageEncodingParam(ImwriteFlags.JpegQuality, jpgQuality)
|
|
};
|
|
byte[] bytes = entry.Image.ImEncode(".jpg", jpgParams);
|
|
|
|
int pictureIdx = workbook.AddPicture(bytes, PictureType.JPEG);
|
|
var drawing = sheet.CreateDrawingPatriarch();
|
|
var anchor = workbook.GetCreationHelper().CreateClientAnchor();
|
|
anchor.Col1 = startCol;
|
|
anchor.Row1 = imageRowStart;
|
|
|
|
int cols = (int)Math.Ceiling(widthCm / 2.0);
|
|
int rows = (int)Math.Ceiling(heightCm / 0.7);
|
|
|
|
anchor.Col2 = startCol + cols;
|
|
anchor.Row2 = imageRowStart + rows;
|
|
|
|
drawing.CreatePicture(anchor, pictureIdx);
|
|
|
|
// Parameters 삽입 (각 set은 column, 각 값은 row)
|
|
int dataStartCol = startCol + cols + 1; // 이미지 오른쪽 첫 컬럼
|
|
int maxParamCount = 0;
|
|
|
|
// ParametersSet의 최대 길이 계산
|
|
foreach (var paramSet in entry.ParametersSets)
|
|
if (paramSet.Count > maxParamCount) maxParamCount = paramSet.Count;
|
|
|
|
// 각 column별 최대 문자열 길이를 저장
|
|
int[] maxColWidths = new int[entry.ParametersSets.Count];
|
|
|
|
// paramValue index 기준으로 row 반복
|
|
for (int i = 0; i < maxParamCount; i++)
|
|
{
|
|
var rowObj = sheet.GetRow(imageRowStart + i) ?? sheet.CreateRow(imageRowStart + i);
|
|
for (int j = 0; j < entry.ParametersSets.Count; j++)
|
|
{
|
|
var paramSet = entry.ParametersSets[j];
|
|
if (i < paramSet.Count)
|
|
{
|
|
string value = paramSet[i];
|
|
var cell = rowObj.GetCell(dataStartCol + j) ?? rowObj.CreateCell(dataStartCol + j);
|
|
cell.SetCellValue(value);
|
|
|
|
// 열 최대 너비 계산
|
|
int length = value.Length;
|
|
if (length > maxColWidths[j]) maxColWidths[j] = length;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 열 너비 적용 (문자수 기준 * 256)
|
|
for (int j = 0; j < entry.ParametersSets.Count; j++)
|
|
{
|
|
sheet.SetColumnWidth(dataStartCol + j, (maxColWidths[j] + 2) * 256); // +2 여유 공간
|
|
}
|
|
|
|
// Content 삽입
|
|
int contentRow = imageRowStart + rows + 1;
|
|
IRow contentRowObj = sheet.GetRow(contentRow) ?? sheet.CreateRow(contentRow);
|
|
ICell contentCell = contentRowObj.GetCell(startCol) ?? contentRowObj.CreateCell(startCol);
|
|
contentCell.SetCellValue(entry.Content);
|
|
}
|
|
|
|
// 엑셀 저장
|
|
public void Save()
|
|
{
|
|
using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
|
|
workbook.Write(fs);
|
|
}
|
|
|
|
// JPEG 품질 변경
|
|
public void SetJpegQuality(int quality)
|
|
{
|
|
jpgQuality = (quality < 0) ? 0 : (quality > 100 ? 100 : quality);
|
|
}
|
|
}
|
|
}
|