-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Setting checkbox value in template #1187
Comments
@ozilion Can be done already, but how do you imagine this function? Do you free-form search for some text, and find the first checkbox to the left of it? Or do you enumerate the checkboxes and search for the n-th one (...with xslt?)? Search for a w:p (paragraph) where the unique id of the w:sdt tag is a certain value?.. in short: how do YOU say "(un)check THAT one".
|
I tried PHPDocx, they use bookmark in checkbox. Defining bookmark variable for each checkbox should work or may be better solution? I have a forms contains many checkboxes in but depending some other criteria i just have to check 1 to 3 of them. For example define bookmark like ${check1} and use in code $template->setChekBox("check", true); |
By the way changing <w14:checked w14:val="1"/> will work |
I thought, or at least docx4j does, set both the ☒ AND the val="1" (or vice versa, text.setValue("☐"); and val="0"). Bookmarks, huh. Nice unobtrusive way to add variables (did not know it). I'll see what I can do, give me a few days. |
Minimal working example. Requires my fork of TemplateProcessor.php (drop-in replacement for 0.13.0/0.14.0, only replace TemplateProcessor.php in your ./vendor/) EDIT: code removed, see branch with production quality code. note: still contains a flaw that it can not find the last checkbox. This is only a code example, no testcases have been written yet. I might need to update my TemplateProcessor to include search-right-from-tag and search-left-from-tag to lessen the code burden. |
I think this is the one of the most expected feature (at least for me) and personally i could use convertion to pdf but it is another matter. In our project we only need now is to change state of any checkbox in templates. Thanks for your efforts, you have enough time :) |
Conversion to pdf is a whole new bag of cats, as it goes word->html->pdf and html markup is lacking if you want more than just the basics. If you need a perfect word to pdf, either get a commercial version or install the commandline version of open/libreoffice, which just works but is very slow and does not scale (or look into UNO if you need speed; search for "unoconv") |
@ozilion Ok, time for you to be my first tester. grab 2 files: From there (you can read the testcases and source to see what it does) $file_dir = storage_path('checkbox_withbookmark.docx');
$template = new \PhpOffice\PhpWord\CheckboxTemplateProcessor($file_dir);
$template->setCheckboxOn('bookmark_1');
$template->setCheckboxOff('bookmark_2');
$template->saveAs(storage_path('app/public/tmp.docx'));
return response()->download(storage_path('app/public/tmp.docx'))->deleteFileAfterSend(true); You also have Because CheckboxTemplateProcessor inherits all from my rewrite of TemplateProcessor, you have also the goodies that TemplateProcessor brings (in fact, we use its segments to do the hard work) I really wish PHPOffice will drop support for PHP5.3.3 soon, because it is better to use traits instead of subclasses. (because you can mix-and-match with traits). |
V13 not working with me, it genereates corrupted files from templates. in v12 i can use it without problem but your files didn't work for me. |
I made it work v13 but $template->setCheckboxOn('bookmark_1'); didn't work. Checkbox still unchecked. But can i see your test word file, may i made a mistake in my template defining bookmark? |
The version does not matter much as you are replacing the full TemplateProcessor with something else. What did not work? Does You should have something like: <w:p>
<w:pPr><w:pStyle w:val="Normal"/><w:rPr></w:rPr></w:pPr>
<w:sdt>
<w:sdtPr>
<w14:checkbox>
<w14:checked w:val="0"/>
<w14:checkedState w:val="2612"/>
<w14:uncheckedState w:val="2610"/>
</w14:checkbox>
</w:sdtPr>
<w:sdtContent>
<w:r>
<w:rPr><w:rFonts w:eastAsia="MS Gothic" w:ascii="MS Gothic" w:hAnsi="MS Gothic"/><w:lang w:val="en-US"/></w:rPr>
<w:t>☐</w:t>
</w:r>
</w:sdtContent>
</w:sdt>
<w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t xml:space="preserve"> </w:t></w:r>
<w:bookmarkStart w:id="0" w:name="${bookmark_1}"/><w:bookmarkEnd w:id="0"/>
<w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t xml:space="preserve">This is </w:t></w:r>
<w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t>a unchecked checkbox</w:t></w:r>
<w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t xml:space="preserve"> </w:t></w:r>
<w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t>${line1}</w:t></w:r>
</w:p> |
Here is a document you requested |
2.AFR-02BasvuruGozdenGecirme-R5.docx At first, the created files cannot be opened it was saying corrupted or broken file. Then i managed to create files succesfully but now only my first of about 25 templates replaced but others remains as original template, variables not converting. New TemplateProcessor not working in v12. Lastly I cannot add bookmark with special characters like ${ and }, using Office Pro 365 Plus. Note: As you see i am using @ instead ${ and }, more suitable for my project. |
Ok, there are several ways to tackle this and you need to choose the most logical method. Your document contains: <w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="tasarim73"/><w:enabled/><w:calcOnExit w:val="0"/>
<w:statusText w:type="text" w:val="@tasarim73@"/>
<w:checkBox><w:sizeAuto/><w:default w:val="0"/></w:checkBox>
</w:ffData>
</w:fldChar> We also have your bookmark (which NEEDS to be unique), which is mixed up with another bookmark. <w:bookmarkStart w:id="1" w:name="tasarim73"/>
<w:bookmarkStart w:id="2" w:name="_GoBack"/>
<w:bookmarkEnd w:id="1"/>
<w:bookmarkEnd w:id="2"/> and we have several copy-pasted, same name: <w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="Onay1"/><w:enabled/><w:calcOnExit w:val="0"/>
<w:checkBox><w:sizeAuto/><w:default w:val="0"/></w:checkBox>
</w:ffData>
</w:fldChar> Now the LibreOffice implementation is totally different from the MSWord implementation. In fact, I can not manipulate a MSWord checkbox in LibreOffice, and reading your reply, editing a LibreOffice checkbox is not possible in MSWord. Sigh. Setting your first checkbox, using the w:ffData w:name is done like this: $file_dir = storage_path('2.AFR-02BasvuruGozdenGecirme-R5.docx');
$template = new \PhpOffice\PhpWord\TemplateProcessor($file_dir);
// \PhpOffice\PhpWord\TemplateProcessor::$ensureMacroCompletion = false;
// quick function that only uses TemplateProcessor
function setCheckboxMS(&$template, $search, $newValue=true){
$template->processSegment(
$search,
'w:checkBox',
\PhpOffice\PhpWord\TemplateProcessor::SEARCH_LEFT,
0,
'MainPart',
function (&$xmlSegment, &$segmentStart, &$segmentEnd, &$part) use ($newValue) {
$newValue = $newValue? 1 : 0;
$count = 0;
$xmlSegment = preg_replace(
[ '~<w:default w:val="[^"]+"(\s?)/>~u' ],
[ '<w:default w:val="'.$newValue.'"\1/>' ],
$xmlSegment,
1,
$count
);
return $xmlSegment; // replace segment and return the $xmlSegment
}
);
}
setCheckboxMS($template, 'w:name="@tasarim73@"', true); // search on w:statusText
setCheckboxMS($template, 'w:val="tasarim73"', true); // search on w:ffData name value
setCheckboxMS($template, 'w:name="tasarim73"', true); // search on bookmark name
setCheckboxMS($template, 'Çalışanların', true); // search on text (careful, NOT guaranteed to work)
setCheckboxMS($template, 'w:val="Onay1"', true); Also note that there is no guarantee that a text is continuous, it could be: It will take a while (weekend) to update CheckboxTemplateProcessor to also allow MSWord's version of checkboxes. Meanwhile, a question: What is the easier setting to search for? Naming the ffData "tasarim73", setting the statusText "@tasarim73@" or adding a bookmark? Because with a bookmark, we find the bookmark and search to the left (SEARCH_LEFT), but with ffData/statusText we have to search to the right (SEARCH_RIGHT) <w:fldChar w:fldCharType="begin">
<w:ffData>
<w:name w:val="tasarim73"/><w:enabled/><w:calcOnExit w:val="0"/>
<w:statusText w:type="text" w:val="@tasarim73@"/>
<w:checkBox><w:sizeAuto/><w:default w:val="0"/></w:checkBox>
</w:ffData>
</w:fldChar> |
note: TemplateProcessor has been updated yet again (bug with search direction, which we use, update recommended). |
Thank you very much for quick responses. |
Ok. In Microsoft Office <w:name w:val="tasarim73"/>section is bookmark of checkbox element and <w:statusText w:type="text" w:val="@tasarim73@"/>is help text of checkbox. Also Microsoft Whatever we choose it should be fastest and guaranted way for setting checkbox. If this 'setCheckboxMS($template, 'w:val="Onay1"', true);' will work, Onay1 can be use as defined name and be unique as well. |
Final update; This way checkboxes i want set correctly and i used PhpWprd v12 with minor hacks. Your code should work directly in v13 without any changes. But this changes, broke other replaces which is, especially all my search values in my templates after chekbox been checked not replacing still remains as template. |
@ozilion You mean that variables like \PhpOffice\PhpWord\TemplateProcessor::$ensureMacroCompletion = false; (or You can also go back to the original TemplateProcessor, and only add the processSegment (and the functions it uses, as they do not have the same name as existing functions. Search AROUND should not work, you have to use search LEFT to search BEFORE the bookmark, use getSegment() to see if what you are grabbing is actually what you want to grab (or log inside the function to a logfile and dump the $xmlSegment) |
@troosan Any news about this to be added to new versions as default feature? |
Fixed by #2509 |
I think still this is one of the most wanted feature of Templates. Can we add this too?
The text was updated successfully, but these errors were encountered: