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,6 +849,40 @@ impl Docx {
for child in &mut self.document.children {
match child {
DocumentChild::Paragraph(paragraph) => {
collect_images_from_paragraph(paragraph, &mut images, &mut image_bufs);
}
DocumentChild::Table(table) => {
for TableChild::TableRow(row) in &mut table.rows {
for TableRowChild::TableCell(cell) in &mut row.cells {
for content in &mut cell.children {
match content {
TableCellContent::Paragraph(paragraph) => {
collect_images_from_paragraph(
paragraph,
&mut images,
&mut image_bufs,
);
}
TableCellContent::Table(_) => {
// TODO: support comment
}
}
}
}
}
}
_ => {}
}
}
(images, image_bufs)
}
}
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 {
@ -864,22 +898,52 @@ impl Docx {
}
}
}
} 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));
}
}
}
}
}
}
DocumentChild::Table(table) => {
for TableChild::TableRow(row) in &mut table.rows {
for TableRowChild::TableCell(cell) in &mut row.cells {
for content in &mut cell.children {
match content {
TableCellContent::Paragraph(paragraph) => {
for child in &mut paragraph.children {
if let ParagraphChild::Run(run) = child {
_ => {}
}
}
} 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
{
if let Some(DrawingData::Pic(pic)) = &mut d.data {
images.push((
pic.id.clone(),
// For now only png supported
@ -893,18 +957,6 @@ impl Docx {
}
}
}
TableCellContent::Table(_) => {
// TODO: support comment
}
}
}
}
}
}
_ => {}
}
}
(images, image_bufs)
}
}

View File

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

View File

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

View File

@ -69487,6 +69487,114 @@ exports[`writer should write inline jpeg image 2`] = `
</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`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<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();
}
}
});
});