Добавьте правила стиля в таблицы pandoc для вывода odt/docx (границы таблиц)
я генерирую некоторые отчеты odt / docx через markdown с помощью knitr и pandoc, и теперь мне интересно, как вы будете формировать таблицы. В первую очередь меня интересует добавление правил (по крайней мере, сверху, снизу и один под заголовком, но было бы неплохо добавить произвольные внутри таблицы).
запуск следующего примера из документации pandoc через pandoc (без каких-либо специальных параметров) просто дает "простую" таблицу без каких-либо правила / цвета / руководства (в любом -t odt
или -t docx
).
+---------------+---------------+--------------------+
| Fruit | Price | Advantages |
+===============+===============+====================+
| Bananas | .34 | - built-in wrapper |
| | | - bright color |
+---------------+---------------+--------------------+
| Oranges | .10 | - cures scurvy |
| | | - tasty |
+---------------+---------------+--------------------+
Я просмотрел "стили" для возможности указания формирования таблицы в ссылке .файлы DOCX/.odt, но не нашел ничего очевидного, кроме стилей" заголовок таблицы "и" содержимое таблицы", оба из которых, похоже, касаются только форматирования текста в таблице.
будучи довольно незнакомым с процессорами документов в стиле WYSIWYG, я теряюсь в том, как продолжить.
5 ответов
вот как я искал, как это сделать:
способ добавить таблицу в Docx-использовать <w:tbl>
- тег. Поэтому я искал это в репозитории github и нашел его в файле (называется Writers / Docx.hs, так что это не большой сюрприз)
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'
Я вообще не знаком с Haskell, но я вижу, что стиль границы жестко закодирован, так как в нем нет переменной:
let borderProps = mknode "w:tcPr" []
[ mknode "w:tcBorders" []
$ mknode "w:bottom" [("w:val","single")] ()
, mknode "w:vAlign" [("w:val","bottom")] () ]
что это значит ?
это означает, что что вы не можете изменить стиль таблиц docx с текущей версией PanDoc. Howewer, есть способ получить свой собственный стиль.
как получить свой собственный стиль ?
- создайте документ Docx со стилем, который вы хотите на своей таблице (создав эту таблицу)
- измените расширение этого файла и распакуйте его
- открыть
word/document.xml
поиск<w:tbl>
- попробуйте узнать, как ваш стиль переводится в XML и изменить в borderProps по тому, что вы видите.
вот тест с бордюрным стилем, который я создал:
и вот соответствующий 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>
как насчет odt ?
Я еще не смотрел на него, спросите, не находите ли вы сами, используя аналогичный метод.
надеюсь, что это поможет и не стесняйтесь спрашивать что-то еще
то же предложение, что и edi9999: взломать xml-содержимое преобразованного docx. И ниже приведен мой R-код для этого.
на tblPr
переменная содержит определение стиля, который будет добавлен в таблицы в docx. Вы можете изменить строку, чтобы удовлетворить свои собственные потребности.
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")
edi9999 имеет лучший ответ, но вот что я делаю:
при создании docx используйте ссылочный docx для получения стилей. Эта ссылка будет содержать кучу других стилей, которые просто не используются Pandoc для создания, но они все еще там. Обычно вы получаете наборы по умолчанию, но вы также можете добавить новый стиль таблицы.
тогда вам нужно только обновить word\document.xml-файл для ссылки на новый стиль таблицы, и вы можете сделать это программно (путем распаковки, запуск sed и обновление архива docx), например:
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
просто добавьте стиль таблицы, что каждый вы хотите, называется "таблица" в файле справки doc。И обновите pandoc до последней версии.