fix: image writer with review (#486)

Co-authored-by: bokuweb <bokuweb@bokuwebnombp.lan>
main
bokuweb 2022-06-03 01:03:16 +09:00 committed by GitHub
parent 37fec82fd8
commit 6fcffc7cfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 244 additions and 36 deletions

View File

@ -849,23 +849,7 @@ impl Docx {
for child in &mut self.document.children { for child in &mut self.document.children {
match child { match child {
DocumentChild::Paragraph(paragraph) => { DocumentChild::Paragraph(paragraph) => {
for child in &mut paragraph.children { collect_images_from_paragraph(paragraph, &mut images, &mut image_bufs);
if let ParagraphChild::Run(run) = child {
for child in &mut run.children {
if let RunChild::Drawing(d) = child {
if let Some(DrawingData::Pic(pic)) = &mut d.data {
images.push((
pic.id.clone(),
// For now only png supported
format!("media/{}.png", pic.id),
));
let b = std::mem::take(&mut pic.image);
image_bufs.push((pic.id.clone(), b));
}
}
}
}
}
} }
DocumentChild::Table(table) => { DocumentChild::Table(table) => {
for TableChild::TableRow(row) in &mut table.rows { for TableChild::TableRow(row) in &mut table.rows {
@ -873,25 +857,11 @@ impl Docx {
for content in &mut cell.children { for content in &mut cell.children {
match content { match content {
TableCellContent::Paragraph(paragraph) => { TableCellContent::Paragraph(paragraph) => {
for child in &mut paragraph.children { collect_images_from_paragraph(
if let ParagraphChild::Run(run) = child { paragraph,
for child in &mut run.children { &mut images,
if let RunChild::Drawing(d) = child { &mut image_bufs,
if let Some(DrawingData::Pic(pic)) = );
&mut d.data
{
images.push((
pic.id.clone(),
// For now only png supported
format!("media/{}.png", pic.id),
));
let b = std::mem::take(&mut pic.image);
image_bufs.push((pic.id.clone(), b));
}
}
}
}
}
} }
TableCellContent::Table(_) => { TableCellContent::Table(_) => {
// TODO: support comment // TODO: support comment
@ -908,6 +878,88 @@ impl Docx {
} }
} }
fn collect_images_from_paragraph(
paragraph: &mut Paragraph,
images: &mut Vec<(String, String)>,
image_bufs: &mut Vec<(String, Vec<u8>)>,
) {
for child in &mut paragraph.children {
if let ParagraphChild::Run(run) = child {
for child in &mut run.children {
if let RunChild::Drawing(d) = child {
if let Some(DrawingData::Pic(pic)) = &mut d.data {
images.push((
pic.id.clone(),
// For now only png supported
format!("media/{}.png", pic.id),
));
let b = std::mem::take(&mut pic.image);
image_bufs.push((pic.id.clone(), b));
}
}
}
} else if let ParagraphChild::Insert(ins) = child {
for child in &mut ins.children {
match child {
InsertChild::Run(run) => {
for child in &mut run.children {
if let RunChild::Drawing(d) = child {
if let Some(DrawingData::Pic(pic)) = &mut d.data {
images.push((
pic.id.clone(),
// For now only png supported
format!("media/{}.png", pic.id),
));
let b = std::mem::take(&mut pic.image);
image_bufs.push((pic.id.clone(), b));
}
}
}
}
InsertChild::Delete(del) => {
for d in &mut del.children {
if let DeleteChild::Run(run) = d {
for child in &mut run.children {
if let RunChild::Drawing(d) = child {
if let Some(DrawingData::Pic(pic)) = &mut d.data {
images.push((
pic.id.clone(),
// For now only png supported
format!("media/{}.png", pic.id),
));
let b = std::mem::take(&mut pic.image);
image_bufs.push((pic.id.clone(), b));
}
}
}
}
}
}
_ => {}
}
}
} else if let ParagraphChild::Delete(del) = child {
for d in &mut del.children {
if let DeleteChild::Run(run) = d {
for child in &mut run.children {
if let RunChild::Drawing(d) = child {
if let Some(DrawingData::Pic(pic)) = &mut d.data {
images.push((
pic.id.clone(),
// For now only png supported
format!("media/{}.png", pic.id),
));
let b = std::mem::take(&mut pic.image);
image_bufs.push((pic.id.clone(), b));
}
}
}
}
}
}
}
}
fn update_document_by_toc( fn update_document_by_toc(
document_children: Vec<DocumentChild>, document_children: Vec<DocumentChild>,
styles: &Styles, styles: &Styles,

View File

@ -87,6 +87,10 @@ impl ElementReader for Run {
if let Ok(drawing) = Drawing::read(r, &attributes) { if let Ok(drawing) = Drawing::read(r, &attributes) {
run = run.add_drawing(drawing); run = run.add_drawing(drawing);
} }
}
// For now, we treat pict ad drawing
XMLElement::Pict => {
} }
XMLElement::FieldChar => { XMLElement::FieldChar => {
if let Ok(f) = read_field_char(&attributes) { if let Ok(f) = read_field_char(&attributes) {

View File

@ -210,6 +210,7 @@ pub enum VXMLElement {
Stroke, Stroke,
Fill, Fill,
TextBox, TextBox,
Shape,
Unsupported, Unsupported,
} }
@ -450,6 +451,7 @@ impl FromStr for VXMLElement {
"stroke" => Ok(VXMLElement::Stroke), "stroke" => Ok(VXMLElement::Stroke),
"fill" => Ok(VXMLElement::Fill), "fill" => Ok(VXMLElement::Fill),
"textbox" => Ok(VXMLElement::TextBox), "textbox" => Ok(VXMLElement::TextBox),
"shape" => Ok(VXMLElement::Shape),
_ => Ok(VXMLElement::Unsupported), _ => Ok(VXMLElement::Unsupported),
} }
} }

View File

@ -69487,6 +69487,114 @@ exports[`writer should write inline jpeg image 2`] = `
</w:document>" </w:document>"
`; `;
exports[`writer should write jpeg image with del 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">
<Relationship Id=\\"rId1\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\\" Target=\\"styles.xml\\" />
<Relationship Id=\\"rId2\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\\" Target=\\"fontTable.xml\\" />
<Relationship Id=\\"rId3\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\\" Target=\\"settings.xml\\" />
<Relationship Id=\\"rId5\\" Type=\\"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\\" Target=\\"commentsExtended.xml\\" />
<Relationship Id=\\"rIdImage4\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\\" Target=\\"media/rIdImage4.png\\" />
</Relationships>"
`;
exports[`writer should write jpeg image with del 2`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"yes\\"?>
<w:document xmlns:o=\\"urn:schemas-microsoft-com:office:office\\" xmlns:r=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\\" xmlns:v=\\"urn:schemas-microsoft-com:vml\\" xmlns:w=\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\" xmlns:w10=\\"urn:schemas-microsoft-com:office:word\\" xmlns:wp=\\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\\" xmlns:wps=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\\" xmlns:wpg=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\\" xmlns:mc=\\"http://schemas.openxmlformats.org/markup-compatibility/2006\\" xmlns:wp14=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\\" xmlns:w14=\\"http://schemas.microsoft.com/office/word/2010/wordml\\" xmlns:w15=\\"http://schemas.microsoft.com/office/word/2012/wordml\\" mc:Ignorable=\\"w14 wp14\\">
<w:body><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /></w:pPr><w:del w:id=\\"2\\" w:author=\\"bokuweb\\" w:date=\\"2021-12-23T18:16:00Z\\"><w:r><w:rPr /><w:drawing>
<wp:inline distT=\\"0\\" distB=\\"0\\" distL=\\"0\\" distR=\\"0\\">
<wp:extent cx=\\"3048000\\" cy=\\"2286000\\" />
<wp:effectExtent b=\\"0\\" l=\\"0\\" r=\\"0\\" t=\\"0\\" />
<wp:wrapNone />
<wp:docPr id=\\"1\\" name=\\"Figure\\" />
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a=\\"http://schemas.openxmlformats.org/drawingml/2006/main\\" noChangeAspect=\\"1\\" />
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a=\\"http://schemas.openxmlformats.org/drawingml/2006/main\\">
<a:graphicData uri=\\"http://schemas.openxmlformats.org/drawingml/2006/picture\\"><pic:pic xmlns:pic=\\"http://schemas.openxmlformats.org/drawingml/2006/picture\\">
<pic:nvPicPr>
<pic:cNvPr id=\\"0\\" name=\\"\\" />
<pic:cNvPicPr>
<a:picLocks noChangeAspect=\\"1\\" noChangeArrowheads=\\"1\\" />
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed=\\"rIdImage4\\" />
<a:srcRect />
<a:stretch>
<a:fillRect />
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode=\\"auto\\">
<a:xfrm>
<a:off x=\\"0\\" y=\\"0\\" />
<a:ext cx=\\"3048000\\" cy=\\"2286000\\" />
</a:xfrm>
<a:prstGeom prst=\\"rect\\">
<a:avLst />
</a:prstGeom>
</pic:spPr>
</pic:pic></a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing></w:r></w:del></w:p><w:sectPr><w:pgSz w:w=\\"11906\\" w:h=\\"16838\\" /><w:pgMar w:top=\\"1985\\" w:right=\\"1701\\" w:bottom=\\"1701\\" w:left=\\"1701\\" w:header=\\"851\\" w:footer=\\"992\\" w:gutter=\\"0\\" /><w:cols w:space=\\"425\\" /><w:docGrid w:type=\\"lines\\" w:linePitch=\\"360\\" /></w:sectPr></w:body>
</w:document>"
`;
exports[`writer should write jpeg image with ins 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">
<Relationship Id=\\"rId1\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\\" Target=\\"styles.xml\\" />
<Relationship Id=\\"rId2\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\\" Target=\\"fontTable.xml\\" />
<Relationship Id=\\"rId3\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\\" Target=\\"settings.xml\\" />
<Relationship Id=\\"rId5\\" Type=\\"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\\" Target=\\"commentsExtended.xml\\" />
<Relationship Id=\\"rIdImage3\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\\" Target=\\"media/rIdImage3.png\\" />
</Relationships>"
`;
exports[`writer should write jpeg image with ins 2`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"yes\\"?>
<w:document xmlns:o=\\"urn:schemas-microsoft-com:office:office\\" xmlns:r=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\\" xmlns:v=\\"urn:schemas-microsoft-com:vml\\" xmlns:w=\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\" xmlns:w10=\\"urn:schemas-microsoft-com:office:word\\" xmlns:wp=\\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\\" xmlns:wps=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\\" xmlns:wpg=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\\" xmlns:mc=\\"http://schemas.openxmlformats.org/markup-compatibility/2006\\" xmlns:wp14=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\\" xmlns:w14=\\"http://schemas.microsoft.com/office/word/2010/wordml\\" xmlns:w15=\\"http://schemas.microsoft.com/office/word/2012/wordml\\" mc:Ignorable=\\"w14 wp14\\">
<w:body><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /></w:pPr><w:ins w:id=\\"1\\" w:author=\\"bokuweb\\" w:date=\\"2021-12-23T18:16:00Z\\"><w:r><w:rPr /><w:drawing>
<wp:inline distT=\\"0\\" distB=\\"0\\" distL=\\"0\\" distR=\\"0\\">
<wp:extent cx=\\"3048000\\" cy=\\"2286000\\" />
<wp:effectExtent b=\\"0\\" l=\\"0\\" r=\\"0\\" t=\\"0\\" />
<wp:wrapNone />
<wp:docPr id=\\"1\\" name=\\"Figure\\" />
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a=\\"http://schemas.openxmlformats.org/drawingml/2006/main\\" noChangeAspect=\\"1\\" />
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a=\\"http://schemas.openxmlformats.org/drawingml/2006/main\\">
<a:graphicData uri=\\"http://schemas.openxmlformats.org/drawingml/2006/picture\\"><pic:pic xmlns:pic=\\"http://schemas.openxmlformats.org/drawingml/2006/picture\\">
<pic:nvPicPr>
<pic:cNvPr id=\\"0\\" name=\\"\\" />
<pic:cNvPicPr>
<a:picLocks noChangeAspect=\\"1\\" noChangeArrowheads=\\"1\\" />
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed=\\"rIdImage3\\" />
<a:srcRect />
<a:stretch>
<a:fillRect />
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode=\\"auto\\">
<a:xfrm>
<a:off x=\\"0\\" y=\\"0\\" />
<a:ext cx=\\"3048000\\" cy=\\"2286000\\" />
</a:xfrm>
<a:prstGeom prst=\\"rect\\">
<a:avLst />
</a:prstGeom>
</pic:spPr>
</pic:pic></a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing></w:r></w:ins></w:p><w:sectPr><w:pgSz w:w=\\"11906\\" w:h=\\"16838\\" /><w:pgMar w:top=\\"1985\\" w:right=\\"1701\\" w:bottom=\\"1701\\" w:left=\\"1701\\" w:header=\\"851\\" w:footer=\\"992\\" w:gutter=\\"0\\" /><w:cols w:space=\\"425\\" /><w:docGrid w:type=\\"lines\\" w:linePitch=\\"360\\" /></w:sectPr></w:body>
</w:document>"
`;
exports[`writer should write line spacing 1`] = ` exports[`writer should write line spacing 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?> "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\"> <Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">

View File

@ -744,4 +744,46 @@ describe("writer", () => {
} }
} }
}); });
test("should write jpeg image with ins", () => {
const buf = Buffer.from(require("./cat"), "base64");
const image = new w.Image(buf).size(320 * 9525, 240 * 9525);
const p = new w.Paragraph().addInsert(
new w.Insert(new w.Run().addImage(image))
.author("bokuweb")
.date("2021-12-23T18:16:00Z")
);
const buffer = new w.Docx().addParagraph(p).build();
writeFileSync("../output/js/image_with_ins.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml/)) {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
});
test("should write jpeg image with del", () => {
const buf = Buffer.from(require("./cat"), "base64");
const image = new w.Image(buf).size(320 * 9525, 240 * 9525);
const p = new w.Paragraph().addDelete(
new w.Delete(new w.Run().addImage(image))
.author("bokuweb")
.date("2021-12-23T18:16:00Z")
);
const buffer = new w.Docx().addParagraph(p).build();
writeFileSync("../output/js/image_with_del.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml/)) {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
});
}); });