如何在 MarkLogic 中创建 multi sheet excel

How to create multi sheet excel in MarkLogic

我想在单个工作簿中创建具有两个 sheet 的 excel 文件。当我尝试使用以下代码时,它会创建一个无法打开的工作簿。 但是,当我创建一个 sheet 时,它会起作用。 请找到这两种情况的附加代码,让我知道我错过了什么。

创建单个 sheet excel(工作)。

declare namespace ms = "http://schemas.openxmlformats.org/spreadsheetml/2006/main" ;
declare namespace ns2 = "http://www.example.com/";

declare function local:AgentReport() 
{ 
<AgentReport>
    <Report>
        <GroupNumber>1</GroupNumber>
        <Quotes>1</Quotes>
        <Converted>1</Converted>
        <Conv_Rate>1</Conv_Rate>
    </Report>
    <Report>
        <GroupNumber>2</GroupNumber>
        <Quotes>2</Quotes>
        <Converted>2</Converted>
        <Conv_Rate>2</Conv_Rate>
    </Report>
</AgentReport>
};
declare function local:getRows( $x ) as element(ms:row)* 
{ 
    let $first-row :=
            <ms:row> 
            {
            for $i in $x/*/*[1]/child::element()
            return 
            <ms:c t="inlineStr"> <ms:is> <ms:t>{fn:node-name($i)}</ms:t> </ms:is> </ms:c> 
            }
            </ms:row>
    return 
        (
        $first-row,

        for $each in $x//Report
        return
        <ms:row> 
        {
        for $i in $each/*
        return 
        <ms:c t="inlineStr"> <ms:is> <ms:t>{$i/string()}</ms:t> </ms:is> </ms:c> 
        }
        </ms:row>
        )
};

declare function local:generate-simple-xl-ooxml( $content-types as node(), $workbook as node(), $rels as node(), $workbookrels as node(), $sheet1 as node() ) as binary() 
{ 
    let $manifest :=    <parts xmlns="xdmp:zip"> 
                        <part>[Content_Types].xml</part> 
                        <part>workbook.xml</part> 
                        <part>_rels/.rels</part> 
                        <part>_rels/workbook.xml.rels</part> 
                        <part>sheet1.xml</part> 
                        </parts> 
    let $parts := ($content-types, $workbook, $rels, $workbookrels, $sheet1) 
    return xdmp:zip-create($manifest, $parts)
};

let $content-types := <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> 
                      <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
                      <Default Extension="xml" ContentType="application/xml"/> 
                      <Override PartName="/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/> 
                      <Override PartName="/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/> 
                      </Types> 

let $workbook :=  <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> 
                  <sheets> 
                  <sheet name="Sheet1" sheetId="1" r:id="rId1" /> 
                  </sheets> 
                  </workbook> 

let $rels :=  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> 
              <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="workbook.xml"/> 
              </Relationships> 

let $workbookrels :=  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> 
                      <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="sheet1.xml"/> 
                      </Relationships> 

let $date := xs:string(fn:current-date())

let $day := fn:tokenize($date, "\+")[1]

let $xml := local:AgentReport()

let $page := xdmp:tidy(xdmp:quote($xml), 
                      <options xmlns="xdmp:tidy">
                      <input-xml>true</input-xml>
                      </options>)[2]

let $tables := $page

let $sheet1 :=   <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> 
                <sheetData> {local:getRows($tables)} </sheetData> 
                </worksheet> 

let $package := local:generate-simple-xl-ooxml($content-types, $workbook, $rels, $workbookrels, $sheet1) 

let $filename := "ExcelTest.xlsx" 

let $disposition := concat("attachment; filename=""",$filename,"""") 

let $x := xdmp:add-response-header("Content-Disposition", $disposition) 

let $x := xdmp:set-response-content-type("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") 

let $insertReport := xdmp:document-insert(concat("/GroupNumberReport/Group-", $day, ".xlsx"), $package, (), "GroupReport")

let $saveReport := xdmp:save(concat("C:\EriePoc\DataStage-Demo\Report\Group-", $day, ".xlsx"), $package)

return fn:true()

创建两个 sheets excel(不工作,即创建损坏的 excelsheet)。

declare namespace ms = "http://schemas.openxmlformats.org/spreadsheetml/2006/main" ;
declare namespace ns2 = "http://www.example.com/";

declare function local:AgentReport() 
{ 
<AgentReport>
    <Report>
        <GroupNumber>1</GroupNumber>
        <Quotes>1</Quotes>
        <Converted>1</Converted>
        <Conv_Rate>1</Conv_Rate>
    </Report>
    <Report>
        <GroupNumber>2</GroupNumber>
        <Quotes>2</Quotes>
        <Converted>2</Converted>
        <Conv_Rate>2</Conv_Rate>
    </Report>
</AgentReport>

};

declare function local:getRows( $x ) as element(ms:row)* 
{ 
    let $first-row :=
            <ms:row> 
            {
            for $i in $x/*/*[1]/child::element()
            return 
            <ms:c t="inlineStr"> <ms:is> <ms:t>{fn:node-name($i)}</ms:t> </ms:is> </ms:c> 
            }
            </ms:row>
    return 
        (
        $first-row,

        for $each in $x//Report
        return
        <ms:row> 
        {
        for $i in $each/*
        return 
        <ms:c t="inlineStr"> <ms:is> <ms:t>{$i/string()}</ms:t> </ms:is> </ms:c> 
        }
        </ms:row>
        )
};

declare function local:generate-simple-xl-ooxml( $content-types as node(), $workbook as node(), $rels as node(), $workbookrels as node(), $sheet1 as node(), $sheet2 as node() ) as binary() 
{ 
    let $manifest :=    <parts xmlns="xdmp:zip"> 
                        <part>[Content_Types].xml</part> 
                        <part>workbook.xml</part> 
                        <part>_rels/.rels</part> 
                        <part>_rels/workbook.xml.rels</part> 
                        <part>sheet1.xml</part>
                        <part>sheet2.xml</part>
                        </parts> 
    let $parts := ($content-types, $workbook, $rels, $workbookrels, $sheet1, $sheet2) 
    return xdmp:zip-create($manifest, $parts)
};

let $content-types := <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> 
                      <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
                      <Default Extension="xml" ContentType="application/xml"/> 
                      <Override PartName="/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/> 
                      <Override PartName="/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
                                <Override PartName="/sheet2.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
                      </Types> 

let $workbook :=  <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> 
                  <sheets>  
                  <sheet name="Sheet1" sheetId="1" r:id="rId1" />
                          <sheet name="Sheet2" sheetId="2" r:id="rId2" />
                  </sheets> 
                  </workbook> 

let $rels :=  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> 
              <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="workbook.xml"/>
                    <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="workbook.xml"/>             
              </Relationships> 

let $workbookrels :=  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> 
                      <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="sheet1.xml"/>
                                <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="sheet2.xml"/>                    
                      </Relationships> 

let $date := xs:string(fn:current-date())

let $day := fn:tokenize($date, "\+")[1]

let $xml := local:AgentReport()

let $page := xdmp:tidy(xdmp:quote($xml), 
                      <options xmlns="xdmp:tidy">
                      <input-xml>true</input-xml>
                      </options>)[2]

let $tables := $page

let $sheet1 :=   <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> 
                <sheetData> {local:getRows($tables)} </sheetData> 
                </worksheet> 

let $sheet2 :=   <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> 
                <sheetData> {local:getRows($tables)} </sheetData> 
                </worksheet> 

let $package := local:generate-simple-xl-ooxml($content-types, $workbook, $rels, $workbookrels, $sheet1, $sheet2) 

let $filename := "ExcelTest.xlsx" 

let $disposition := concat("attachment; filename=""",$filename,"""") 

let $x := xdmp:add-response-header("Content-Disposition", $disposition) 

let $x := xdmp:set-response-content-type("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") 

let $insertReport := xdmp:document-insert(concat("/GroupNumberReport/Group-", $day, ".xlsx"), $package, (), "GroupReport")

let $saveReport := xdmp:save(concat("C:\EriePoc\DataStage-Demo\Report\Group-", $day, ".xlsx"), $package)

return fn:true()

问题是您有一个不需要的额外 Relationship 元素,这会导致问题。

将您的 $rels 变量更改为:

let $rels :=  
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> 
    <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="workbook.xml"/>           
  </Relationships> 

遗憾的是,MS Office 通常不会提供任何有用的指示,指出哪里有错误或有什么错误。事情要么奏效,要么就失败了,几乎没有关于错误的信息。

我发现测试小的更改以及使用 MS Office 应用程序中的工作实例文件很有帮助,保存,然后比较 *.xlsx zip 中的各个文件以发现两者之间的细微差别有效和无效。