/// <summary> /// 将此单元格的位置用I3MergeRange表示 /// 为合并单元格的第一个单元格时,返回整个合并区间 /// 为合并单元格的其他单元格时,只返回单元格本身 /// </summary> public I3MergeRange GetRange_Mode2(I3ReportData reportData) { I3MergeRange range = this.MergState == I3MergeState.FirstCell ? reportData.GetMergeRange(row, col) : null; if (range == null) { range = new I3MergeRange((short)row, (short)col, (short)row, (short)col); } return(range); }
/// <summary> /// 拆分单个合并单元格 /// </summary> /// <param name="m"></param> /// <param name="reportData"></param> /// <returns></returns> private static I3MergeRange[] splitMemrgeRangeInDifPage(I3MergeRange m, I3ReportData reportData) { List <I3MergeRange> list = new List <I3MergeRange>(); I3PrintArea startArea = getPrintAreaByRowIndex(m.StartRow, reportData); I3PrintArea endArea = getPrintAreaByRowIndex(m.EndRow, reportData); //不在数据区,不做处理 if (startArea == null || endArea == null) { list.Add(m); return(list.ToArray()); } //在同一页,不做处理 if (startArea.Index == endArea.Index) { list.Add(m); return(list.ToArray()); } //开始拆分 I3MergeRange m1 = new I3MergeRange(m.StartRow, m.StartCol, startArea.MaxDataAreaRowIndex, m.EndCol); if (m1.EndRow > m1.StartRow || m1.EndCol > m1.StartCol)//判断是否是一个有效的合并单元格 { list.Add(m1); } I3MergeRange m2 = new I3MergeRange(endArea.MinDataAreaRowIndex, m.StartCol, m.EndRow, m.EndCol); //m2的样式同m I3ReportCell mCell = reportData.Rows[m.StartRow][m.StartCol]; I3ReportCell m2Cell = reportData.Rows[m2.StartRow][m2.StartCol]; m2Cell.MergState = I3MergeState.FirstCell; m2Cell.StyleName = mCell.StyleName; if (!string.IsNullOrEmpty(mCell.Text)) { m2Cell.Text = "..."; } if (m2.EndRow - m2.StartRow > 0) //后面的部分超过了一行 { I3MergeRange[] newArr = splitMemrgeRangeInDifPage(m2, reportData); //继续拆分 list.AddRange(newArr); } else//后面的部分只有一行 { if (m2.EndCol > m2.StartCol)//存在列的合并 { list.Add(m2); } } return(list.ToArray()); }
/// <summary> /// 增加一个合并区域 /// </summary> /// <param name="startRow"></param> /// <param name="startCol"></param> /// <param name="endRow"></param> /// <param name="endCol"></param> public void AddMergeRange(int startRow, int startCol, int endRow, int endCol) { if (mergeDic == null) { mergeDic = new Dictionary <int, Dictionary <int, I3MergeRange> >(); } if (!mergeDic.ContainsKey(startRow)) { mergeDic.Add(startRow, new Dictionary <int, I3MergeRange>()); } if (!mergeDic[startRow].ContainsKey(startCol)) { mergeDic[startRow].Add(startCol, null); } mergeDic[startRow][startCol] = new I3MergeRange(startRow, startCol, endRow, endCol); }
/// <summary> /// 重新计算单元格的大小,借以调整行、列的大小 /// prepareNarrow:是否处理内容缩放 /// </summary> /// <param name="reportData"></param> /// <param name="row"></param> /// <param name="col"></param> private static void ReCalCellSize(I3ReportData reportData, int row, int col, bool prepareNarrow) { #region 获取单元格、样式、合并区域对象 I3ReportCell cell = reportData.GetCellItem(row, col); if (cell == null || cell.MergState == I3MergeState.Merged) //单元格为空,或者是被合并的,不需要重新计算 { return; } I3ReportCellStyle style = reportData.GetCellStyle(cell.StyleName); //没有样式设置,不用重新计算 if (style == null) { return; } I3MergeRange range = cell.MergState == I3MergeState.FirstCell ? reportData.GetMergeRange(row, col) : null; if (range == null) { range = new I3MergeRange((short)row, (short)col, (short)row, (short)col); } #endregion #region 得到默认宽度、高度 int width = 0; int height = 0; for (int i = range.StartRow; i <= range.EndRow; i++) { height += reportData[i].Height; } for (int i = range.StartCol; i <= range.EndCol; i++) { width += reportData.Cols[i].Width; } if (width == 0 || height == 0) { return; } #endregion II3CellRenderer renderer = I3CellRendererBuilder.GetRenderer(reportData[row][col]); SizeF needSize = renderer.CalCellNeedSize(width, height, style, cell); if (needSize != SizeF.Empty) { renderer.AdjustCellSize(width, height, needSize, style, cell, range, reportData, prepareNarrow); } }
/// <summary> /// 将此单元格的位置用I3MergeRange表示 /// 为合并单元格时,返回合并区域 /// </summary> public I3MergeRange GetRange_Mode1(I3ReportData reportData) { I3MergeRange range = null; switch (this.MergState) { case I3MergeState.Merged: I3ReportCell startCell = reportData.GetMergedStartedCell(this.Row, this.Col); range = reportData.GetMergeRange(startCell.Row, startCell.Col); break; case I3MergeState.FirstCell: range = reportData.GetMergeRange(this.Row, this.Col); break; default: range = new I3MergeRange((short)this.Row, (short)this.Col, (short)this.Row, (short)this.Col); break; } return(range); }
public override void AdjustCellSize(int width, int height, SizeF needSizeF, I3ReportCellStyle style, I3ReportCell cell, I3MergeRange range, I3ReportData reportData, bool prepareNarrow) { //不做处理 }
private void exportAreaToSheet(I3PrintArea area, HSSFWorkbook workbook, ISheet sheet, ref int rowCount, Dictionary <string, HSSFCellStyle> styleDic, Dictionary <string, IFont> fontDic) { HSSFCellStyle emptyStyle = createEmptyStyle(workbook); //导出行、单元格 foreach (int rowIndex in area.AllRows) { //设置行高 rowCount++; IRow row = sheet.CreateRow(rowCount - 1); I3ReportRow rowData = area.ReportData.Rows[rowIndex]; if (rowData.PageBreak) //分页符 { sheet.SetRowBreak(rowCount - 1); } double dh = (double)rowData.Height * (double)15.305838; dh = dh * (double)1.1; int height = (int)Math.Ceiling(dh); row.Height = (short)height; //设置文本 int colIndex = -1; foreach (I3ReportCell cellData in rowData.Cells) { colIndex++; ICell cell = row.CreateCell(colIndex); bool hasReturnInText = false; if (cellData.MergState != I3MergeState.Merged) { hasReturnInText = !string.IsNullOrEmpty(cellData.Text) && cellData.Text.IndexOf("{r}") >= 0; if (cellData is I3ReportImageCell) { I3ReportImageCell imageCell = (I3ReportImageCell)cellData; byte[] bytes = imageCell.ImageData; if (bytes != null && bytes.Length > 0) { try { int pictureIdx = workbook.AddPicture(bytes, PictureType.JPEG); HSSFPatriarch patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch(); // 插图片的位置 HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2) 后面再作解释 int row1 = rowCount - 1; int row2 = rowCount - 1; int col1 = colIndex; int col2 = colIndex; if (cellData.MergState == I3MergeState.FirstCell) { I3MergeRange mr = area.ReportData.GetMergeRange(cellData.Row, cellData.Col); row2 = rowCount - 1 + mr.EndRow - mr.StartRow; col2 = mr.EndCol; } HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, col1, row1, col2, row2); //把图片插到相应的位置 HSSFPicture pict = (HSSFPicture)patriarch.CreatePicture(anchor, pictureIdx); } catch { } } } else { string text = string.IsNullOrEmpty(cellData.Text) ? "" : cellData.Text.Replace("{r}", "\r\n"); //特殊符号....使用替换符如{1级钢筋}{WL}{屈特比} cell.SetCellValue(text); } } //设置样式 int lastRowIndex = area.AllRows[area.AllRows.Length - 1]; bool isLastRow = rowData.Row == lastRowIndex; bool isLastCol = cellData.Col == area.ReportData.Cols.Length - 1; setCellStyle(workbook, sheet, cell, area, cellData, styleDic, fontDic, hasReturnInText, isLastRow, isLastCol, emptyStyle); //设置合并 if (cellData.MergState == I3MergeState.FirstCell) { I3MergeRange mr = area.ReportData.GetMergeRange(cellData.Row, cellData.Col); CellRangeAddress ra = new CellRangeAddress(rowCount - 1, rowCount - 1 + mr.EndRow - mr.StartRow, mr.StartCol, mr.EndCol); sheet.AddMergedRegion(ra); } } } }
public override void AdjustCellSize(int width, int height, SizeF needSizeF, I3ReportCellStyle style, I3ReportCell cell, I3MergeRange range, I3ReportData reportData, bool prepareNarrow) { I3ReportImageCell imageCell = cell as I3ReportImageCell; int doubleSplit = ImageSplit * 2; if (needSizeF.Width > width - doubleSplit || needSizeF.Height > height - doubleSplit) { switch (style.AdjustSize) { case I3AdjustSize.扩大单元格: #region 扩大单元格 if (needSizeF.Width > width - doubleSplit) { float pro = (needSizeF.Width + doubleSplit) / width; for (int i = range.StartCol; i <= range.EndCol; i++) { reportData.Cols[i].Width = (int)(reportData.Cols[i].Width * pro); } } if (needSizeF.Height > height - doubleSplit) { float pro = (needSizeF.Height + doubleSplit) / height; for (int i = range.StartRow; i <= range.EndRow; i++) { reportData[i].Height = (int)(reportData[i].Height * pro); } } cell.StringTrimming = StringTrimming.None; #endregion break; case I3AdjustSize.缩小内容: #region 缩小内容 if (prepareNarrow) { //先使宽度一致 imageCell.CalWidth = width - doubleSplit; imageCell.CalHeight = imageCell.Height * imageCell.CalWidth / imageCell.Width; //如果高度太大,则使高度一致 if (imageCell.CalHeight > height - doubleSplit) { imageCell.CalHeight = height - doubleSplit; imageCell.CalWidth = imageCell.Width * imageCell.CalHeight / imageCell.Height; } } #endregion break; default: //都不变,调整为图片不按比例缩小 #region 图片不按比例缩小 imageCell.CalWidth = width - doubleSplit; imageCell.CalHeight = height - doubleSplit; #endregion break; } } }
/// <summary> /// 计算输出区域 (以内容输出区域左上角为0,0开始计算、不考虑缩放、页眉页脚平移) /// 如果是合并单元格,包含整个合并区域 /// 必须经过平移、缩放放才有意义 /// </summary> /// <param name="bitmap"></param> /// <param name="reportData"></param> /// <param name="cell"></param> private static RectangleF CalCellDrawRect_UnScale(I3ReportDatas reportDatas, I3ReportCell cell, I3PrintArea area, I3ReportCell mergedCell) { //X、Y先求原单元格的 int row = mergedCell == null ? cell.Row : mergedCell.Row; int col = mergedCell == null ? cell.Col : mergedCell.Col; I3RowColType rowType = area.ReportData[row].Type; I3RowColType colType = area.ReportData.Cols[col].Type; //Width、Heigth求合并的 I3MergeRange range = cell.GetRange_Mode2(area.ReportData); RectangleF rect = new RectangleF(0F, 0F, 0F, 0F); #region Y IList <int> rows = null; switch (rowType) { case I3RowColType.页眉: rows = area.HeaderRows.Keys; break; case I3RowColType.页脚: rows = area.FooterRows.Keys; break; default: rows = area.DataRows.Keys; break; } foreach (int i in rows) { if (i < row) { rect.Y += area.ReportData[i].Height; } } #endregion #region Height for (int i = range.StartRow; i <= range.EndRow; i++) //高度为合并区域的高度的和 { rect.Height += area.ReportData[i].Height; } #endregion #region X IList <int> cols = null; switch (colType) { case I3RowColType.页眉: cols = area.HeaderCols.Keys; break; case I3RowColType.页脚: cols = area.FooterCols.Keys; break; default: cols = area.DataCols.Keys; break; } foreach (int i in cols) { if (i < col) { rect.X += area.ReportData.Cols[i].Width; } } #endregion #region Width for (int i = range.StartCol; i <= range.EndCol; i++) { rect.Width += area.ReportData.Cols[i].Width; } #endregion #region 画合并单元格的部分时,左移、上移 if (mergedCell != null) { for (int i = cell.Row; i < mergedCell.Row; i++) { rect.Y -= area.ReportData[i].Height; } for (int i = cell.Col; i < mergedCell.Col; i++) { rect.X -= area.ReportData.Cols[i].Width; } } #endregion return(rect); }
public virtual void AdjustCellSize(int width, int height, SizeF needSizeF, I3ReportCellStyle style, I3ReportCell cell, I3MergeRange range, I3ReportData reportData, bool prepareNarrow) { int fontSize = style.FontSize == 0 ? 13 : style.FontSize; //字体默认值13像素 if (needSizeF.Width > width || needSizeF.Height > height) { switch (style.AdjustSize) { case I3AdjustSize.扩大单元格: #region 扩大单元格 if (needSizeF.Width > width) { needSizeF.Width += 4F; //加大一点 float pro = needSizeF.Width / width; for (int i = range.StartCol; i <= range.EndCol; i++) { reportData.Cols[i].Width = (int)(reportData.Cols[i].Width * pro); } } if (needSizeF.Height > height) { float pro = needSizeF.Height / height; for (int i = range.StartRow; i <= range.EndRow; i++) { reportData[i].Height = (int)(reportData[i].Height * pro); } } cell.StringTrimming = StringTrimming.None; #endregion break; case I3AdjustSize.缩小内容: #region 缩小内容 if (prepareNarrow) { //换行时字号递减1进行测试 , 不换行时根据宽度 if (style.WordWrap) { if (needSizeF.Height > height) { float calFontSize = fontSize; while (calFontSize > 5 && needSizeF.Height > height) { calFontSize--; needSizeF = CalCellNeedSize(width, height, style, cell, calFontSize); } cell.CalFontSize = calFontSize; cell.HasCalFontSize = true; cell.StringTrimming = StringTrimming.None; } } else { if (needSizeF.Width > width) { float pro2 = width / needSizeF.Width; float calFontSize = fontSize * pro2; calFontSize = calFontSize > 5F ? calFontSize : 5F; //最小5号 cell.CalFontSize = calFontSize; cell.StringTrimming = StringTrimming.None; } } } #endregion break; default: #region 都不变 cell.StringTrimming = StringTrimming.None; #endregion break; } } }
public virtual void DrawCellBorder(Graphics g, float scale, I3ReportData reportData, I3ReportCell cell, RectangleF rect, I3ReportCellStyle style) { I3MergeRange range = cell.GetRange_Mode1(reportData); if (range == null) { return; } if (cell.Row == range.StartRow) { #region 边框 if (style.TopBorder != null) { using (Brush brush = new SolidBrush(style.TopBorder.Color)) { using (Pen pen = new Pen(brush)) { //pen.Width = style.TopBorder.Width * scale; //缩放不影响边框 pen.Width = style.TopBorder.Width; if (pen.Width > 0 && pen.Width < 1) { pen.Width = 1; } pen.Color = style.TopBorder.Color; pen.DashStyle = style.TopBorder.Type; g.DrawLine(pen, new PointF(rect.X, rect.Y), new PointF(rect.X + rect.Width, rect.Y)); } } } #endregion } if (cell.Col == range.StartCol) { #region 左边框 if (style.LeftBorder != null) { using (Brush brush = new SolidBrush(style.LeftBorder.Color)) { using (Pen pen = new Pen(brush)) { //pen.Width = style.LeftBorder.Width * scale; pen.Width = style.LeftBorder.Width; if (pen.Width > 0 && pen.Width < 1) { pen.Width = 1; } pen.Color = style.LeftBorder.Color; pen.DashStyle = style.LeftBorder.Type; g.DrawLine(pen, new PointF(rect.X, rect.Y), new PointF(rect.X, rect.Y + rect.Height)); } } } #endregion } if (cell.Row == range.EndRow) { #region 边框 if (style.BottomBorder != null) { using (Brush brush = new SolidBrush(style.BottomBorder.Color)) { using (Pen pen = new Pen(brush)) { //pen.Width = style.BottomBorder.Width * scale; pen.Width = style.BottomBorder.Width; if (pen.Width > 0 && pen.Width < 1) { pen.Width = 1; } pen.Color = style.BottomBorder.Color; pen.DashStyle = style.BottomBorder.Type; g.DrawLine(pen, new PointF(rect.X, rect.Y + rect.Height), new PointF(rect.X + rect.Width, rect.Y + rect.Height)); } } } #endregion } //if (cell.Col == range.EndCol) //如果是除边框空白列外最右侧的列,强制画右边框线(要求表格4周都有单位1的空白行列) if (range.EndCol == reportData.Cols[reportData.Cols.Length - 1].Col - 1) { #region 右边框 if (style.RightBorder != null) { using (Brush brush = new SolidBrush(style.RightBorder.Color)) { using (Pen pen = new Pen(brush)) { //pen.Width = style.RightBorder.Width * scale; pen.Width = style.RightBorder.Width; if (pen.Width > 0 && pen.Width < 1) { pen.Width = 1; } pen.Color = style.RightBorder.Color; pen.DashStyle = style.RightBorder.Type; g.DrawLine(pen, new PointF(rect.X + rect.Width, rect.Y), new PointF(rect.X + rect.Width, rect.Y + rect.Height)); } } } #endregion } }