Dodawanie reguł stylizacji w tabelach pandoc dla wyjścia ODT / docx (obramowania tabel)

Generuję raporty ODT / docx za pomocą markdown przy użyciu knitr i pandoc i zastanawiam się teraz, jak byś poszedł o formatowanie tabel. Przede wszystkim interesuje mnie dodawanie reguł (przynajmniej góra, dół i jedna pod nagłówkiem, ale możliwość dodawania dowolnych w tabeli też byłaby mile widziana).

Uruchomienie poniższego przykładu z dokumentacji pandoc poprzez pandoc (bez żadnych specjalnych parametrów) po prostu daje "zwykłą" tabelę bez żadnych reguł/kolorów/prowadnic (w -t odt lub -t docx).

+---------------+---------------+--------------------+
| Fruit         | Price         | Advantages         |
+===============+===============+====================+
| Bananas       | $1.34         | - built-in wrapper |
|               |               | - bright color     |
+---------------+---------------+--------------------+
| Oranges       | $2.10         | - cures scurvy     |
|               |               | - tasty            |
+---------------+---------------+--------------------+

Przejrzałem "style" dla możliwości określenia formatowania tabeli w referencji .docx/odt nie znalazł nic oczywistego poza stylami" nagłówek tabeli "i" zawartość tabeli", które wydają się dotyczyć tylko formatowania tekstu w tabeli.

Będąc raczej nieznanym z procesorami dokumentów w stylu WYSIWYG, Nie wiem, jak kontynuować.

Author: edi9999, 2013-07-25

5 answers

Oto jak Szukałem jak to zrobić:

Sposobem dodawania tabeli w Docx jest użycie znacznika <w:tbl>. Więc Szukałem tego w repozytorium github i znalazłem to w tym pliku (o nazwie Writers/Docx.hs, więc nie jest to wielka niespodzianka)

blockToOpenXML opts (Table caption aligns widths headers rows) = do
  let captionStr = stringify caption
  caption' <- if null caption
                 then return []
                 else withParaProp (pStyle "TableCaption")
                      $ blockToOpenXML opts (Para caption)
  let alignmentFor al = mknode "w:jc" [("w:val",alignmentToString al)] ()
  let cellToOpenXML (al, cell) = withParaProp (alignmentFor al)
                                    $ blocksToOpenXML opts cell
  headers' <- mapM cellToOpenXML $ zip aligns headers
  rows' <- mapM (\cells -> mapM cellToOpenXML $ zip aligns cells)
           $ rows
  let borderProps = mknode "w:tcPr" []
                    [ mknode "w:tcBorders" []
                      $ mknode "w:bottom" [("w:val","single")] ()
                    , mknode "w:vAlign" [("w:val","bottom")] () ]
  let mkcell border contents = mknode "w:tc" []
                            $ [ borderProps | border ] ++
                            if null contents
                               then [mknode "w:p" [] ()]
                               else contents
  let mkrow border cells = mknode "w:tr" [] $ map (mkcell border) cells
  let textwidth = 7920  -- 5.5 in in twips, 1/20 pt
  let mkgridcol w = mknode "w:gridCol"
                       [("w:w", show $ (floor (textwidth * w) :: Integer))] ()
  return $
    [ mknode "w:tbl" []
      ( mknode "w:tblPr" []
        ( [ mknode "w:tblStyle" [("w:val","TableNormal")] () ] ++
          [ mknode "w:tblCaption" [("w:val", captionStr)] ()
          | not (null caption) ] )
      : mknode "w:tblGrid" []
        (if all (==0) widths
            then []
            else map mkgridcol widths)
      : [ mkrow True headers' | not (all null headers) ] ++
      map (mkrow False) rows'
      )
    ] ++ caption'

W ogóle nie znam Haskella, ale widzę, że styl border-style jest zakodowany na twardo, ponieważ nie ma w nim żadnej zmiennej:

let borderProps = mknode "w:tcPr" []
                    [ mknode "w:tcBorders" []
                      $ mknode "w:bottom" [("w:val","single")] ()
                    , mknode "w:vAlign" [("w:val","bottom")] () ]
Co to znaczy ?

To oznacza, że nie możesz zmienić stylu docx tabele z aktualną wersją PanDoc. Howewer, jest sposób na własny styl.

Jak zdobyć własny styl ?

  1. Utwórz dokument Docx ze stylem, który chcesz umieścić na swojej tabeli (tworząc tę tabelę)
  2. zmień rozszerzenie tego pliku i rozpakuj go
  3. Otwórz word/document.xml i wyszukaj <w:tbl>
  4. spróbuj dowiedzieć się, jak Twój styl tłumaczy się w XML i zmienić obramowania zgodnie z tym, co widzisz.

Oto test z border - styl, który stworzyłem: Niestandardowy styl obramowania

I tutaj jest odpowiedni XML:

<w:tblBorders>
  <w:top w:val="dotted" w:sz="18" w:space="0" w:color="C0504D" w:themeColor="accent2"/>
  <w:left w:val="dotted" w:sz="18" w:space="0" w:color="C0504D" w:themeColor="accent2"/>
  <w:bottom w:val="dotted" w:sz="18" w:space="0" w:color="C0504D" w:themeColor="accent2"/>
  <w:right w:val="dotted" w:sz="18" w:space="0" w:color="C0504D" w:themeColor="accent2"/>
  <w:insideH w:val="dotted" w:sz="18" w:space="0" w:color="C0504D" w:themeColor="accent2"/>
  <w:insideV w:val="dotted" w:sz="18" w:space="0" w:color="C0504D" w:themeColor="accent2"/>
</w:tblBorders>

A co z odt ?

Jeszcze na to nie spojrzałem, spytaj, czy sam nie znajdziesz podobnej metody.

Mam nadzieję, że to pomoże i nie wahaj się zapytać o coś więcej

 21
Author: edi9999,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-25 16:13:16

Ta sama sugestia co edi9999: zhakuj zawartość XML przekonwertowanego docx. A oto mój kod R do robienia tego.

Zmienna tblPr zawiera definicję stylu dodawanego do tabel w docx. Możesz zmodyfikować ciąg, aby zaspokoić własne potrzeby.

require(XML)

docx.file <- "report.docx"
tblPr <- '<w:tblPr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:tblStyle w:val="a8"/><w:tblW w:w="0" w:type="auto"/><w:tblBorders><w:top w:val="single" w:sz="4" w:space="0" w:color="000000" w:themeColor="text1"/><w:left w:val="single" w:sz="4" w:space="0" w:color="000000" w:themeColor="text1"/><w:bottom w:val="single" w:sz="4" w:space="0" w:color="000000" w:themeColor="text1"/><w:right w:val="single" w:sz="4" w:space="0" w:color="000000" w:themeColor="text1"/><w:insideH w:val="single" w:sz="4" w:space="0" w:color="000000" w:themeColor="text1"/><w:insideV w:val="single" w:sz="4" w:space="0" w:color="000000" w:themeColor="text1"/></w:tblBorders><w:jc w:val="center"/></w:tblPr>'

## unzip the docx converted by Pandoc
system(paste("unzip", docx.file, "-d temp_dir"))
document.xml <- "temp_dir/word/document.xml"

doc <- xmlParse(document.xml)
tbl <- getNodeSet(xmlRoot(doc), "//w:tbl")
tblPr.node <- lapply(1:length(tbl), function (i)
                   xmlRoot(xmlParse(tblPr)))
added.Pr <- names(xmlChildren(tblPr.node[[1]]))
for (i in 1:length(tbl)) {
    tbl.node <- tbl[[i]]
    if ('tblPr' %in% names(xmlChildren(tbl.node))) {
        children.Pr <- xmlChildren(xmlChildren(tbl.node)$tblPr)
        for (j in length(added.Pr):1) {
            if (added.Pr[j] %in% names(children.Pr)) {
                replaceNodes(children.Pr[[added.Pr[j]]],
                             xmlChildren(tblPr.node[[i]])[[added.Pr[j]]])
            } else {
                ## first.child <- children.Pr[[1]]
                addSibling(children.Pr[['tblStyle']],
                           xmlChildren(tblPr.node[[i]])[[added.Pr[j]]],
                           after=TRUE)
            }
        }
    } else {
        addSibling(xmlChildren(tbl.node)[[1]], tblPr.node[[i]], after=FALSE)
    }
}

## save hacked xml back to docx
saveXML(doc, document.xml, indent = F)
setwd("temp_dir")
system(paste("zip -r ../", docx.file, " *", sep=""))
setwd("..")
system("rm -fr temp_dir")
 9
Author: lcn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-25 16:38:15

Edi9999 ma najlepszą odpowiedź ale oto co robię:

Podczas tworzenia docx, użyj docx odniesienia, aby uzyskać style. To odniesienie będzie zawierać stertę innych stylów, które po prostu nie są używane przez Pandoc do tworzenia, ale nadal tam są. Zazwyczaj otrzymasz domyślne zestawy, ale możesz również dodać nowy styl tabeli.

Następnie wystarczy zaktualizować word \ document.plik xml, aby odwołać się do nowego stylu tabeli, i można to zrobić programowo (rozpakowując, uruchamiając sed, i aktualizowanie archiwum docx), np.:

7z.exe x mydoc.docx word\document.xml
sed "s/<w:tblStyle w:val=\"TableNormal\"/<w:tblStyle w:val=\"NewTableStyle\"/g" word\document.xml > word\document2.xml
copy word\document2.xml word\document.xml /y
7z.exe u mydoc.docx word\document.xml
 4
Author: gbjbaanb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-18 14:04:32

Dodaj styl tabeli o nazwie "TableNormal" W referencji.docx.

 2
Author: henry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-08 04:39:15

Wystarczy dodać styl tabeli co każdy chcesz o nazwie "tabela" w pliku reference-doc.I zaktualizuj pandoc do najnowszej wersji.

 0
Author: ZHUOQI LI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-02 11:08:01