programing

EPLUS로 생성된 Excel 파일의 읽을 수 없는 콘텐츠

cafebook 2023. 7. 2. 20:58
반응형

EPLUS로 생성된 Excel 파일의 읽을 수 없는 콘텐츠

EPLUS 라이브러리를 사용하여 템플릿에서 Excel 파일을 생성할 때 약간의 문제가 있습니다.파일에는 다음 시트에 피벗 테이블을 채우는 데 사용되는 데이터가 포함된 첫 번째 스프레드시트가 있습니다.

생성된 파일을 열면 다음과 같은 오류 메시지가 표시됩니다. "Excel은 'sampleFromTemplate'에서 읽을 수 없는 내용을 찾았습니다.xlsx'입니다. 이 문제집의 내용을 복구하시겠습니까?이 워크북의 출처를 신뢰하는 경우 예를 클릭합니다."

"예"를 클릭하면 파일에 대한 복구 요약과 다음이 포함된 xml 형식의 로그 파일에 대한 링크가 나타납니다.

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <logFileName>error095080_01.xml</logFileName>
    <summary>Errors were detected in file  'C:\TEMP\sampleFromTemplate.xlsx'</summary>
    <repairedRecords summary="Following is a list of repairs:">
        <repairedRecord>Repaired Records: Table from /xl/tables/table1.xml part (Table)</repairedRecord>
    </repairedRecords>
</recoveryLog>

이는 피벗 테이블에 사용할 데이터를 나타내기 위해 코드에 정의한 명명된 범위("표 1")에 의해 발생한 것으로 보입니다.템플릿에 "Table1"이라는 이름의 "Table Name"이 이미 있지만, Excel Package를 통해 액세스할 수 없는 것 같습니다.작업 계획표.이름 모음입니다.EPLUS는 처음이고 엑셀은 별로 실험하지 않아서 제가 어디서 잘못하고 있는지 이해할 수 없습니다.다음은 파일을 생성하는 코드 부분입니다.

private string GenerateFromTemplate(string fileName, string templateName, DataTable tab)
{
    FileInfo newFile = new FileInfo(string.Format("C:\\MyPath\\{0}.xlsx", fileName));
    FileInfo templateFile = new FileInfo(string.Format("C:\\MyPath\\{0}.xlsx", templateName));

    try
    {
        using (ExcelPackage pkg = new ExcelPackage(newFile, templateFile))
        {
            ExcelWorksheet sheet = pkg.Workbook.Worksheets["MyDataSheet"];
            ExcelRange range = sheet.Cells[string.Format("A1:U{0}", dt.Rows.Count)];
            pkg.Workbook.Names.Add("Table1", range as ExcelRangeBase);

            int sheetRowIndex = 2;

            foreach (DataRow row in this.dt.Rows)
            {
                sheet.Cells[sheetRowIndex, 1].Value = row["Row1"];
                sheet.Cells[sheetRowIndex, 2].Value = row["Row2"];
                [...]
                sheet.Cells[sheetRowIndex, 21].Value = row["Row21"];

                sheetRowIndex++;
            }

            pkg.Save();
            return newFile.FullName;
        }
    }
    catch (IOException ex) { return ex.Message; }
}

어쨌든 피벗 테이블은 올바르게 채워집니다. 그런데 왜 이런 일이 발생합니까?

감사합니다 :-)

저는 이 문제에 직접 부딪혀 해결했습니다. 다른 사람이 이 문제에 부딪힐 경우 해결책을 여기에 두었습니다.

이것은 asp.net 을 사용한 것입니다. 분명한 이유로 그렇지 않으면 적용할 수 없습니다.

제 문제는 테이블 범위가 아니라, 이플러스가 파일을 생성하는 데 문제가 없었고, 오히려 서버 응답이 엑셀 파일에 페이지 응답을 추가하고 있어서 파일이 유효하지 않은 것이 분명했습니다.파일을 보낸 후 바로 서버 응답을 종료하면 문제가 해결됩니다. 다음과 같은 이점이 있습니다.

Response.BinaryWrite(pck.GetAsByteArray());  // send the file
Response.End();

문제가 해결되지는 않았지만 지금은 그 이유를 정확히 알고 있습니다.이 "표 1"은 명명된 범위가 아니라 워크시트의 "표" 컬렉션을 통해 액세스할 수 있는 표였습니다.

문제는 EP Plus의 Tables 컬렉션과 Tables 개체가 모두 읽기 전용이기 때문에 코드에서 Tables 차원을 정의할 수 없으며 필요에 따라 테이블을 제거하거나 새 차원을 추가할 수도 없다는 것입니다.EPLUS의 저자는 이미 메시지가 거의 3년이 지났기 때문에 언젠가 (여기여기) 버스가 구현될 수도 있다고 언급했습니다. 저는 그렇게 될 것이라는 희망이 거의 없다고 생각합니다.

어쨌든, 저는 이것이 같은 문제에 직면한 사람들에게 도움이 되기를 바랍니다.

[EDIT] 마침내 문제를 우회할 수 있는 방법을 생각해냈습니다. ExcelTable 개체에는 "TableXml"이라는 쓰기 가능한 속성이 있으며, 여기에는 물론 범위가 있는 테이블의 xml 정의가 포함되어 있습니다.제 경우 내용은 다음과 같습니다.

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
    <table dataCellStyle="Normal 2" headerRowCellStyle="Normal 2" headerRowDxfId="70" totalsRowShown="0" insertRow="1" ref="A1:U2" displayName="Table1" name="Table1" id="1" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
        <autoFilter ref="A1:U2"/>
        <tableColumns count="21">
            <tableColumn dataCellStyle="Normal 2" name="Activity" id="1"/>
            <tableColumn dataCellStyle="Normal 2" name="Category" id="21"/>
            [...]
            <tableColumn dataCellStyle="Normal 2" name="Closed Year" id="20" dataDxfId="62"/>
        </tableColumns>
        <tableStyleInfo name="TableStyleMedium9" showColumnStripes="0" showRowStripes="1" showLastColumn="0" showFirstColumn="0"/>
</table>

여기서 관심을 끄는 것은 "table" 및 "autoFilter" 노드의 "ref" 속성입니다. 값을 변경하면 테이블의 범위를 재정의할 수 있기 때문입니다.

저는 다음과 같이 진행했습니다.

XmlDocument tabXml = sheet.Tables(0).TableXml;
XmlNode tableNode = tabXml.ChildNodes[1];
tableNode.Attributes["ref"].Value = string.Format("A1:U{0}", dt.Rows.Count + 1);
XmlNode autoFilterNode = tableNode.ChildNodes[0];
autoFilterNode.Attributes["ref"].Value = string.Format("A1:U{0}", dt.Rows.Count + 1);

그리고 이제 내 엑셀 파일은 내 데이터의 실제 범위에 맞는 "표 1"로 적절하게 생성되었습니다!

저는 이 문제를 해결하는 데 약 4시간을 보냈습니다. 저의 문제와 해결책이 게시물에 없기 때문에, 저는 미래의 방문객을 위해 그것을 쓰고 있습니다.

제 문제는 엑셀 시트의 중복된 열 때문에 발생했습니다.한 열에 공간을 추가한 후 문제가 해결되었습니다.흥미로운 부분은 MS excel을 통해 피벗 테이블을 생성했을 때 오류가 발생한 적이 없으며, eplus를 사용하여 엑셀 파일에 피벗 테이블을 생성했을 때만 발생했다는 것입니다.버그를 찾기 어렵게 만드는 것

각 행 뒤에 열 구분 기호를 추가하는 버그가 있을 때 이 문제가 발생했습니다.

head1{tab}head2{tab}
col11{tab}col21{tab}
col22{tab}col22{tab}

마지막 열 이후의 추가 탭에서 Excel 스프레드시트를 이와 같은 방식으로 구분하여 제거하면 문제가 해결됩니다.참고사중다니입용▁the다니를 사용하고 있습니다.LoadFromText텍스트 데이터에서 한 번에 전체 시트를 로드할 수 있습니다.이것은 OP의 문제가 아닐 수도 있지만, 아마도 미래의 검색자들은 이것이 도움이 될 것입니다.

머리글에 특수 형식(윈딩 글꼴이 특수 기호를 표시하는 데 사용됨)이 있는 표를 사용하여 워크북을 편집할 때 이 문제가 발생했습니다.메시지를 수정하기 위해 서식을 제거해야 했습니다.

다른 설정(스트림 반환), 동일한 문제(손상된 테이블 레코드).저의 경우 문제는 Excel Package에 대한 명시적인 호출이었습니다.저장():

using (var excelPackage = new ExcelPackage())
{
    /* ... removed code for clarity */

    // caused the stream to contain the file 2 times, 
    // save is already called by GetAsByteArray()                
    //excelPackage.Save(); 

    return new MemoryStream(excelPackage.GetAsByteArray());
}

C#과 eplus를 사용하여 Table에서 모든 행을 제거할 때 내 문제가 해결되었습니다.

언급URL : https://stackoverflow.com/questions/20906666/unreadable-content-in-excel-file-generated-with-epplus

반응형