EPPlus icon indicating copy to clipboard operation
EPPlus copied to clipboard

When used (excelpackage.doadjustdrawings = false) to copy shape, Shapes can not be placed in a specific location

Open 93910676wangd opened this issue 3 years ago • 3 comments

When using (excelpackage.doadjustdrawings = false), the shapes will overlap. In order to see clearly, I manually moved the position of the shapes a little epplus version 5.8.12 shape-ng

When used version 5.8.6 (excelpackage.doadjustdrawings = false), there is no problem. Shapes can be placed in a specific location shape-ok

sample source

using (ExcelPackage excelPackage = new ExcelPackage(@"g:\system.xlsx"))
            {
                excelPackage.DoAdjustDrawings = false;
                int lngHeadRow = 3;
                int lngPageCnt = 48;
                int lngPageRecCnt = 45;
                int lngRowCount = 0;
                int lngPage = 0;
                int lngCnt = 0;

                ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[0];
                lngRowCount = 77;
                string strDtm = DateTime.Now.ToString("yyyy.MM.dd");
                lngPage = (lngRowCount % lngPageRecCnt) == 0 ? lngRowCount / lngPageRecCnt : (lngRowCount / lngPageRecCnt) + 1;
               if (lngPage > 1)
                {
                    for (lngCnt = 1; lngCnt < lngPage; lngCnt++)
                    {
                        worksheet.CopyRows(1, lngPageCnt, lngPageCnt * lngCnt + 1);
                    }
                }
                excelPackage.SaveAs(@"G:\aaa.xlsx");
            }
public void CopyRows(this ExcelWorksheet excelWorksheet, int sourceFrom, int sourceTo, int dest)
        {
            CopyRows(excelWorksheet, sourceFrom, sourceTo, dest, dest + sourceTo - sourceFrom, null);
        }

 public void CopyRows(this ExcelWorksheet excelWorksheet, int sourceFrom, int sourceTo, int destFrom, int destTo,
            ExcelRangeCopyOptionFlags? excelRangeCopyOptionFlags)
        {
            excelWorksheet.Cells[sourceFrom.ToString() + ":" + sourceTo].Copy(
                excelWorksheet.Cells[destFrom.ToString() + ":" + destTo], excelRangeCopyOptionFlags);

            for (int i = destFrom; i <= destTo; i++)
            {
                excelWorksheet.Row(i).Height = excelWorksheet.Row(sourceFrom + i - destFrom).Height;
            }

            int copyFrom;
            int copyTo;

            if ((sourceTo - sourceFrom) < 2)
            {
                copyFrom = sourceFrom;
                copyTo = sourceTo;
            }
            else
            {
                copyFrom = sourceFrom + 1;
                copyTo = sourceTo - 1;
            }

            //copy shape
            List<ExcelDrawing> drawingsList = excelWorksheet.Drawings.Where(d => (copyFrom - 1 <= d.From.Row && d.From.Row <= copyTo - 1)
                                                                              || (copyFrom - 1 <= d.To.Row && d.To.Row <= copyTo - 1)).ToList();

            CopyShape(excelWorksheet, drawingsList, destFrom, destTo, sourceFrom);
        }

private void CopyShape(ExcelWorksheet excelWorksheet, List<ExcelDrawing> drawingsList, int destFrom, int destTo, int sourceFrom)
        {
            foreach (ExcelDrawing drawing in drawingsList)
            {
                if (typeof(ExcelShape).Equals(drawing.GetType()))
                {

                    var sourceShape = (ExcelShape)drawing;
                    var shapeName = sourceShape.Name + destFrom.ToString();

                    while (excelWorksheet.Drawings[shapeName] != null)
                    {
                        shapeName += destTo.ToString();
                    }

                    var newShape = excelWorksheet.Drawings.AddShape(shapeName, sourceShape);
                    newShape.From.Row = destFrom + sourceShape.From.Row - sourceFrom;
                    newShape.From.RowOff = sourceShape.From.RowOff;

                    newShape.To.Row = destFrom + sourceShape.To.Row - sourceFrom;
                    newShape.To.RowOff = sourceShape.To.RowOff;
                }
            }
        }

Because there are many rows to copy, i have to use it (excelpackage.doadjustdrawings = false). If don't use it, the copy row will become very slow。 https://github.com/EPPlusSoftware/EPPlus/issues/162 Is there any good solution?

There is no problem with version 5.8.6 After upgrading to 5.8.12, the shapes in the upper right corner overlap. I'm afraid it's the degradation of epplus. Please confirm.

attachment files: system.xlsx aaa-ok-5.8.6.xlsx aaa-ng-5.8.12.xlsx

93910676wangd avatar Aug 04 '22 09:08 93910676wangd

I will have a look at this.

JanKallman avatar Aug 05 '22 08:08 JanKallman

This is a bug as EPPlus doesn't update the Xml when saving the package. I'll provide a fix shortly. You can workaround this issue by updating the xml when setting the value using the UpdateXml method:

  var newShape = excelWorksheet.Drawings.AddShape(shapeName, sourceShape);
  newShape.From.Row = destFrom + sourceShape.From.Row - sourceFrom;
  newShape.From.RowOff = sourceShape.From.RowOff;
  //Update the drawing xml 
 newShape.From.UpdateXml();

  //Update the drawing xml 
  newShape.To.Row = destFrom + sourceShape.To.Row - sourceFrom;
  newShape.To.RowOff = sourceShape.To.RowOff;
  newShape.To.UpdateXml();

JanKallman avatar Aug 05 '22 09:08 JanKallman

Thank you for your quick reply and look forward to the version update

93910676wangd avatar Aug 05 '22 09:08 93910676wangd

Fixed in 5.8.13 and 6.0.7

JanKallman avatar Aug 31 '22 07:08 JanKallman