docx-rs icon indicating copy to clipboard operation
docx-rs copied to clipboard

copy a docx contain images with docx-rs let you see........

Open jiabotao opened this issue 1 year ago • 0 comments

use std::fs::File;
use std::io::{Read};
use docx_rs::*;

fn main() {
    let mut file = File::open("./aaa.docx").unwrap();
    let mut buf = vec![];
    file.read_to_end(&mut buf).unwrap();
    let docx = read_docx(&buf).unwrap();

    let new_docx = copy_docx(docx);

    let path = std::path::Path::new("./alignment.docx");
    let file = File::create(path).unwrap();
    new_docx.build().pack(file).unwrap()
}


fn copy_docx(source_docx:Docx)-> Docx{
    let mut docx = Docx::new();
    let images = source_docx.images;
    let mut children= source_docx.document.children;
    let mut newchildren:Vec<DocumentChild>= vec![];
    for i in 0..children.len(){
        let child = children.get_mut(i).unwrap();
        match child {
            DocumentChild::Paragraph(paragraph) => {//要解决如何替换paragraph
                let mut paragraph_children = paragraph.children.clone();
                let mut new_paragraph_children:Vec<ParagraphChild> = vec![];
                for j in 0..paragraph_children.len(){
                    let paragraph_child = paragraph_children.get_mut(j).unwrap();
                    match paragraph_child {//需要在run中修改paragraph_child并且push到new_paragraph_children
                        ParagraphChild::Run(run) => {//需要便利run_children修改run_child并拷贝回run_children
                            let mut run_children = run.children.clone();
                            let mut new_run_children:Vec<RunChild> = vec![];
                            for k in 0..run_children.len(){
                                let run_child = run_children.get_mut(k).unwrap();
                                match run_child {
                                    RunChild::Drawing(ref mut drawing_box) => {
                                        let draw = drawing_box.data.take().unwrap();
                                        match draw {
                                            DrawingData::Pic(mut pic) => {
                                                let copy = images.clone();
                                                let image_id = pic.clone().id;
                                                for (current_id, description, image, png) in copy {
                                                    // 使用 title, description, image, png
                                                    if current_id == image_id{
                                                        pic.image = image.clone().0;
                                                    }
                                                }

                                                let image_run = RunChild::Drawing(Box::from(Drawing::new().pic(pic.clone())));
                                                new_run_children.push(image_run.clone());
                                            }
                                            DrawingData::TextBox(_) => {
                                                println!("发现TextBox");
                                            }
                                        }
                                    }
                                    _ => {
                                        new_run_children.push(run_child.clone());
                                    }
                                }
                            }
                            run.children = new_run_children;

                            new_paragraph_children.push(ParagraphChild::Run(Box::from(run.clone())));
                        }
                        _ => {
                            new_paragraph_children.push(paragraph_child.clone());
                        }
                    }
                }
                paragraph.children = new_paragraph_children;

                // paragraph是一个整体,用它创建Box<Paragraph>,然后封装为DocumentChild,最后newchildren添加DocumentChild
                // let paragraph = paragraph.clone().reset_children(new_paragraph_children);
                // let new_child = DocumentChild::Paragraph(Box::from(paragraph));
                let owned_value = std::mem::take(&mut *paragraph);
                let new_child = DocumentChild::Paragraph(owned_value);
                newchildren.push(new_child)
            }
            _ => {newchildren.push(child.clone());}
        }

    }
    docx.document.children.append(&mut newchildren);

    docx
}

jiabotao avatar Aug 30 '24 20:08 jiabotao