feat: Support top level bookmark (#133)

main
bokuweb 2020-09-02 18:23:53 +09:00 committed by GitHub
parent e143a80216
commit 5dcd4d73ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 2 deletions

View File

@ -0,0 +1,13 @@
use docx_rs::*;
pub fn main() -> Result<(), DocxError> {
let path = std::path::Path::new("./output/bookmark.docx");
let file = std::fs::File::create(&path).unwrap();
Docx::new()
.add_bookmark_start(1, "hello")
.add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello")))
.add_bookmark_end(1)
.build()
.pack(file)?;
Ok(())
}

View File

@ -1,7 +1,7 @@
use serde::ser::{SerializeStruct, Serializer};
use serde::Serialize;
use super::{Paragraph, SectionProperty, Table};
use super::*;
use crate::documents::BuildXML;
use crate::xml_builder::*;
@ -17,6 +17,8 @@ pub struct Document {
pub enum DocumentChild {
Paragraph(Paragraph),
Table(Table),
BookmarkStart(BookmarkStart),
BookmarkEnd(BookmarkEnd),
}
impl Serialize for DocumentChild {
@ -37,6 +39,18 @@ impl Serialize for DocumentChild {
t.serialize_field("data", c)?;
t.end()
}
DocumentChild::BookmarkStart(ref c) => {
let mut t = serializer.serialize_struct("BookmarkStart", 2)?;
t.serialize_field("type", "bookmarkStart")?;
t.serialize_field("data", c)?;
t.end()
}
DocumentChild::BookmarkEnd(ref c) => {
let mut t = serializer.serialize_struct("BookmarkEnd", 2)?;
t.serialize_field("type", "bookmarkEnd")?;
t.serialize_field("data", c)?;
t.end()
}
}
}
}
@ -71,6 +85,18 @@ impl Document {
self.children.push(DocumentChild::Table(t));
self
}
pub fn add_bookmark_start(mut self, id: usize, name: impl Into<String>) -> Self {
self.children
.push(DocumentChild::BookmarkStart(BookmarkStart::new(id, name)));
self
}
pub fn add_bookmark_end(mut self, id: usize) -> Self {
self.children
.push(DocumentChild::BookmarkEnd(BookmarkEnd::new(id)));
self
}
}
impl BuildXML for Document {
@ -83,6 +109,8 @@ impl BuildXML for Document {
match c {
DocumentChild::Paragraph(p) => b = b.add_child(p),
DocumentChild::Table(t) => b = b.add_child(t),
DocumentChild::BookmarkStart(s) => b = b.add_child(s),
DocumentChild::BookmarkEnd(e) => b = b.add_child(e),
}
}
b.add_child(&self.section_property).close().close().build()

View File

@ -112,6 +112,7 @@ impl Docx {
self.document_rels.has_numberings = true;
}
}
_ => {}
}
}
self.document = d;
@ -138,6 +139,16 @@ impl Docx {
self
}
pub fn add_bookmark_start(mut self, id: usize, name: impl Into<String>) -> Docx {
self.document = self.document.add_bookmark_start(id, name);
self
}
pub fn add_bookmark_end(mut self, id: usize) -> Docx {
self.document = self.document.add_bookmark_end(id);
self
}
pub fn add_table(mut self, t: Table) -> Docx {
if t.has_numbering {
// If this document has numbering, set numberings.xml to document_rels.
@ -247,6 +258,7 @@ impl Docx {
}
}
}
_ => {}
}
}
@ -305,6 +317,7 @@ impl Docx {
}
}
}
_ => {}
}
}
// If this document has comments, set comments.xml to document_rels.
@ -371,6 +384,7 @@ impl Docx {
}
}
}
_ => {}
}
}
(image_ids, images)

View File

@ -2,6 +2,7 @@ import { saveAs } from "file-saver";
import("../js").then((w) => {
const buf = new w.Docx()
.addBookmarkStart(0, "Hello")
.addParagraph(
new w.Paragraph()
.addRun(new w.Run().addText("Hello "))
@ -29,6 +30,7 @@ import("../js").then((w) => {
)
.addCommentEnd(new w.CommentEnd(2))
)
.addBookmarkEnd(0)
.docId("12345678-1234-1234-1234-1234567890AB")
.build();
saveAs(new Blob([buf]), "hello.docx");

View File

@ -48,7 +48,7 @@ const convertBorderType = (t: BorderType) => {
};
export class Docx {
children: (Paragraph | Table)[] = [];
children: (Paragraph | Table | BookmarkStart | BookmarkEnd)[] = [];
hasNumberings = false;
abstractNumberings: AbstractNumbering[] = [];
numberings: Numbering[] = [];
@ -62,6 +62,16 @@ export class Docx {
return this;
}
addBookmarkStart(id: number, name: string) {
this.children.push(new BookmarkStart(id, name));
return this;
}
addBookmarkEnd(id: number) {
this.children.push(new BookmarkEnd(id));
return this;
}
addTable(t: Table) {
if (t.hasNumberings) {
this.hasNumberings = true;
@ -452,6 +462,10 @@ export class Docx {
} else if (child instanceof Table) {
let t = this.buildTable(child);
docx = docx.add_table(t);
} else if (child instanceof BookmarkStart) {
docx = docx.add_bookmark_start(child.id, child.name);
} else if (child instanceof BookmarkEnd) {
docx = docx.add_bookmark_end(child.id);
}
});

View File

@ -18,6 +18,16 @@ impl Docx {
self
}
pub fn add_bookmark_start(mut self, id: usize, name: &str) -> Self {
self.0 = self.0.add_bookmark_start(id, name);
self
}
pub fn add_bookmark_end(mut self, id: usize) -> Docx {
self.0 = self.0.add_bookmark_end(id);
self
}
pub fn add_table(mut self, t: Table) -> Docx {
self.0.document = self.0.document.add_table(t.take());
self